/*
 * 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 <string.h>

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

#include "src/trace_processor/sqlite.h"
#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");
}

util::Status StringTable::Init(int, const char* const*, Schema* schema) {
  *schema = Schema(
      {
          Table::Column(Column::kStringId, "id", ColumnType::kUint),
          Table::Column(Column::kString, "str", ColumnType::kString),
      },
      {Column::kStringId});
  return util::OkStatus();
}

std::unique_ptr<Table::Cursor> StringTable::CreateCursor() {
  return std::unique_ptr<Table::Cursor>(new Cursor(this));
}

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(StringTable* table)
    : Table::Cursor(table), storage_(table->storage_), table_(table) {}

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

int StringTable::Cursor::Filter(const QueryConstraints&, sqlite3_value**) {
  *this = Cursor(table_);
  num_rows_ = storage_->string_count();
  return SQLITE_OK;
}

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
