/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/string_table.h"

#include <sqlite3.h>
#include <string.h>

#include <algorithm>
#include <bitset>
#include <numeric>

#include "src/trace_processor/sqlite_utils.h"
#include "src/trace_processor/trace_storage.h"

namespace perfetto {
namespace trace_processor {

StringTable::StringTable(sqlite3*, const TraceStorage* storage)
    : storage_(storage) {}

void StringTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<StringTable>(db, storage, "strings");
}

base::Optional<Table::Schema> StringTable::Init(int, const char* const*) {
  return Schema(
      {
          Table::Column(Column::kStringId, "id", ColumnType::kUint),
          Table::Column(Column::kString, "str", ColumnType::kString),
      },
      {Column::kStringId});
}

std::unique_ptr<Table::Cursor> StringTable::CreateCursor(
    const QueryConstraints&,
    sqlite3_value**) {
  return std::unique_ptr<Table::Cursor>(new Cursor(storage_));
}

int StringTable::BestIndex(const QueryConstraints&, BestIndexInfo* info) {
  info->order_by_consumed = false;  // Delegate sorting to SQLite.
  info->estimated_cost = static_cast<uint32_t>(storage_->string_count());
  return SQLITE_OK;
}

StringTable::Cursor::Cursor(const TraceStorage* storage) : storage_(storage) {
  num_rows_ = storage->string_count();
}

StringTable::Cursor::~Cursor() = default;

int StringTable::Cursor::Next() {
  row_++;
  return SQLITE_OK;
}

int StringTable::Cursor::Eof() {
  return row_ >= num_rows_;
}

int StringTable::Cursor::Column(sqlite3_context* context, int col) {
  StringId string_id = static_cast<StringId>(row_);
  switch (col) {
    case Column::kStringId:
      sqlite3_result_int64(context, static_cast<sqlite3_int64>(row_));
      break;
    case Column::kString:
      sqlite3_result_text(context, storage_->GetString(string_id).c_str(), -1,
                          sqlite_utils::kSqliteStatic);
      break;
  }
  return SQLITE_OK;
}

}  // namespace trace_processor
}  // namespace perfetto
