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

namespace perfetto {
namespace trace_processor {

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

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

Table::Schema StatsTable::CreateSchema(int, const char* const*) {
  return Schema(
      {
          Table::Column(Column::kKey, "key", ColumnType::kString),
          Table::Column(Column::kValue, "value", ColumnType::kInt),
      },
      {Column::kKey});
}

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

int StatsTable::BestIndex(const QueryConstraints&, BestIndexInfo*) {
  return SQLITE_OK;
}

StatsTable::Cursor::Cursor(const TraceStorage* storage) : storage_(storage) {}

int StatsTable::Cursor::Column(sqlite3_context* context, int N) {
  switch (N) {
    case Column::kKey:
      sqlite3_result_text(context, KeyForRow(row_), -1, nullptr);
      break;
    case Column::kValue:
      sqlite3_result_int(context, ValueForRow(row_));
      break;
    default:
      PERFETTO_FATAL("Unknown column %d", N);
      break;
  }
  return SQLITE_OK;
}

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

int StatsTable::Cursor::Eof() {
  return row_ >= Row::kMax;
}

const char* StatsTable::Cursor::KeyForRow(uint8_t row) {
  switch (row) {
    case StatsTable::Row::kMismatchedSchedSwitch:
      return "mismatched_ss";
    default:
      PERFETTO_FATAL("Unknown row %u", row);
  }
}

int StatsTable::Cursor::ValueForRow(uint8_t row) {
  switch (row) {
    case StatsTable::Row::kMismatchedSchedSwitch: {
      auto val = storage_->stats().mismatched_sched_switch_tids_;
      return static_cast<int>(val);
    }
    default:
      PERFETTO_FATAL("Unknown row %u", row);
  }
}

}  // namespace trace_processor
}  // namespace perfetto
