// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "federated/example_database.h"

#include <cinttypes>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <bits/stdint-intn.h>
#include <sqlite3.h>

#include "federated/utils.h"

namespace federated {

namespace {

constexpr char kMetaTableName[] = "metatable";

// Populates SQL where clause with given start and end time if they are not zero
// values, returns an empty string (i.e. no-op) otherwise.
std::string MaybeWhereClause(const base::Time& start_time,
                             const base::Time& end_time) {
  if (start_time == base::Time() && end_time == base::Time())
    return std::string();

  DCHECK(start_time < end_time)
      << "Invalid time range: start_time must < end_time";
  DCHECK(start_time >= base::Time::UnixEpoch())
      << "Invalid time range: start_time must >= UnixEpoch()";
  return base::StringPrintf("WHERE timestamp>%" PRId64
                            " AND timestamp<=%" PRId64,
                            start_time.InMillisecondsSinceUnixEpoch(),
                            end_time.InMillisecondsSinceUnixEpoch());
}

// Used in ExampleCount to return number of examples.
int ExampleCountCallback(void* const /* int* const */ data,
                         const int col_count,
                         char** const cols,
                         char** const /* names */) {
  DCHECK(data != nullptr);
  DCHECK(cols != nullptr);

  int example_count = 0;
  if (col_count != 1 || cols[0] == nullptr ||
      !base::StringToInt(cols[0], &example_count)) {
    LOG(ERROR) << "Invalid example count results";
    return SQLITE_ERROR;
  }

  auto* const output = static_cast<int*>(data);
  *output = example_count;
  return SQLITE_OK;
}

// Used in CheckIntegrity to extract state code and result string from SQL
// exec.
int IntegrityCheckCallback(void* const /* std::string* const */ data,
                           int const col_count,
                           char** const cols,
                           char** const /* names */) {
  DCHECK(data != nullptr);
  DCHECK(cols != nullptr);

  if (col_count != 1 || cols[0] == nullptr) {
    LOG(ERROR) << "Invalid integrity check results";
    return SQLITE_ERROR;
  }

  auto* const integrity_result = static_cast<std::string*>(data);
  integrity_result->assign(cols[0]);
  return SQLITE_OK;
}

// Used in TableExists to extract state code and table_count from SQL
// exec.
int TableExistsCallback(void* const /* int* const */ data,
                        const int col_count,
                        char** const cols,
                        char** const /* names */) {
  DCHECK(data != nullptr);
  DCHECK(cols != nullptr);

  auto* const table_count = static_cast<int*>(data);
  if (col_count != 1 || cols[0] == nullptr ||
      !base::StringToInt(cols[0], table_count)) {
    LOG(ERROR) << "Table existence check failed";
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}

int GetAllTableNamesCallback(
    void* const /* std::vector<std::string>* const */ data,
    const int col_count,
    char** const cols,
    char** const /* names */) {
  DCHECK(data != nullptr);
  DCHECK(cols != nullptr);

  auto* const all_table_names = static_cast<std::vector<std::string>*>(data);
  if (col_count != 1) {
    LOG(ERROR) << "GetAllTableNames failed";
    return SQLITE_ERROR;
  }
  for (size_t i = 0; i < sizeof(cols) / sizeof(char*); i++) {
    if (cols[i] == nullptr) {
      LOG(ERROR) << "GetAllTableNames gets unexpected nullptr at index " << i;
      return SQLITE_ERROR;
    }
    all_table_names->push_back(std::string(cols[i]));
  }

  return SQLITE_OK;
}

}  // namespace

ExampleDatabase::Iterator::Iterator() : stmt_(nullptr) {}

ExampleDatabase::Iterator::Iterator(sqlite3* const db,
                                    const std::string& table_name,
                                    const base::Time& start_time,
                                    const base::Time& end_time,
                                    bool descending,
                                    const size_t limit) {
  if (db == nullptr) {
    stmt_ = nullptr;
    return;
  }

  const std::string order = descending ? "DESC" : std::string();
  const std::string limit_clause =
      limit > 0 ? base::StringPrintf("LIMIT %zu", limit) : std::string();

  const std::string sql_code = base::StringPrintf(
      "SELECT id, example, timestamp FROM '%s' %s ORDER BY id %s %s;",
      table_name.c_str(), MaybeWhereClause(start_time, end_time).c_str(),
      order.c_str(), limit_clause.c_str());
  const int result =
      sqlite3_prepare_v2(db, sql_code.c_str(), -1, &stmt_, nullptr);

  if (result != SQLITE_OK) {
    LOG(ERROR) << "Couldn't compile iteration statement: "
               << sqlite3_errmsg(db);
    Close();
  }
}

ExampleDatabase::Iterator::Iterator(sqlite3* const db,
                                    const std::string& table_name)
    : ExampleDatabase::Iterator::Iterator(db,
                                          table_name,
                                          base::Time(),
                                          base::Time(),
                                          /*descending=*/false,
                                          /*limit=*/0) {}

ExampleDatabase::Iterator::Iterator(ExampleDatabase::Iterator&& o)
    : stmt_(o.stmt_) {
  o.stmt_ = nullptr;
}

ExampleDatabase::Iterator& ExampleDatabase::Iterator::operator=(
    Iterator&& other) {
  if (stmt_ != nullptr) {
    Close();
  }
  stmt_ = other.stmt_;
  other.stmt_ = nullptr;

  return *this;
}

ExampleDatabase::Iterator::~Iterator() {
  Close();
}

absl::StatusOr<ExampleRecord> ExampleDatabase::Iterator::Next() {
  if (stmt_ == nullptr) {
    return absl::InvalidArgumentError("Invalid sqlite3 statment");
  }

  // Execute retrieval step.
  const int code = sqlite3_step(stmt_);
  if (code == SQLITE_DONE) {
    Close();
    return absl::OutOfRangeError("End of iterator reached");
  }
  if (code != SQLITE_ROW) {
    Close();
    return absl::InvalidArgumentError("Couldn't retrieve next example");
  }

  // Extract step results.
  const int64_t id = sqlite3_column_int64(stmt_, 0);
  const unsigned char* const example_buffer =
      static_cast<const unsigned char*>(sqlite3_column_blob(stmt_, 1));
  const int example_buffer_len = sqlite3_column_bytes(stmt_, 1);
  const int64_t java_ts = sqlite3_column_int64(stmt_, 2);
  if (id <= 0 || example_buffer == nullptr || example_buffer_len <= 0 ||
      java_ts < 0) {
    Close();
    return absl::InvalidArgumentError("Failed to extract example");
  }

  // Populate output struct.
  ExampleRecord example_record;
  example_record.id = id;
  example_record.serialized_example =
      std::string(example_buffer, example_buffer + example_buffer_len);
  example_record.timestamp =
      base::Time::FromMillisecondsSinceUnixEpoch(java_ts);
  return example_record;
}

void ExampleDatabase::Iterator::Close() {
  sqlite3_finalize(stmt_);
  stmt_ = nullptr;
}

ExampleDatabase::ExampleDatabase(const base::FilePath& db_path)
    : db_path_(db_path), db_(nullptr, nullptr) {
  // Checks that sqlite3 is compiled with threading mode = Serialized, so that
  // the db connection can be used in multiple threads. See
  // https://www.sqlite.org/threadsafe.html for more information.
  DCHECK_EQ(1, sqlite3_threadsafe());
}

ExampleDatabase::~ExampleDatabase() {
  Close();
}

bool ExampleDatabase::Init(const std::unordered_set<std::string>& table_names) {
  // SQLITE_OPEN_FULLMUTEX means sqlite3 threadding mode = serialized so that
  // it's safe to access the same database connection in multiple threads.
  // This is the default when `sqlite3_threadsafe() == 1` but no harm to make a
  // double insurance with this flag.
  sqlite3* db_ptr;
  const int result = sqlite3_open_v2(
      db_path_.MaybeAsASCII().c_str(), &db_ptr,
      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL);
  db_ = std::unique_ptr<sqlite3, decltype(&sqlite3_close)>(db_ptr,
                                                           &sqlite3_close);
  if (result != SQLITE_OK) {
    LOG(ERROR) << "Failed to connect to database: "
               << sqlite3_errmsg(db_.get());
    db_ = nullptr;
    return false;
  }

  // Prepares meta table.
  if (!TableExists(kMetaTableName) && !CreateMetaTable()) {
    LOG(ERROR) << "Failed to prepare meta table";
    Close();
    return false;
  }

  // Prepares client tables.
  for (const auto& table_name : table_names) {
    if ((!TableExists(table_name) && !CreateClientTable(table_name))) {
      LOG(ERROR) << "Failed to prepare table " << table_name;
      Close();

      return false;
    }
  }

  return true;
}

bool ExampleDatabase::IsOpen() const {
  return db_.get() != nullptr;
}

bool ExampleDatabase::Close() {
  if (!IsOpen()) {
    return true;
  }

  // If the database is successfully closed, db_ pointer must be released.
  // Otherwise sqlite3_close will be called again on already released db_
  // pointer by the destructor, which will result in undefined behavior.
  int result = sqlite3_close(db_.get());
  if (result != SQLITE_OK) {
    // This should never happen
    LOG(ERROR) << "Failed to close database: " << sqlite3_errmsg(db_.get());
    return false;
  }

  db_.release();
  return true;
}

bool ExampleDatabase::CheckIntegrity() const {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to check integrity of a closed database";
    return false;
  }

  // Integrity_check(N) returns a single row and a single column with string
  // "ok" if there is no error. Otherwise a maximum of N rows are returned
  // with each row representing a single error.
  std::string integrity_result;
  ExecResult result = ExecSql("PRAGMA integrity_check(1)",
                              IntegrityCheckCallback, &integrity_result);
  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to check integrity: " << result.error_msg;
    return false;
  }

  return integrity_result == "ok";
}

bool ExampleDatabase::DeleteOutdatedExamples(
    const base::TimeDelta& example_ttl) const {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to delete examples from a closed database";
    return false;
  }

  std::vector<std::string> all_table_names;
  const ExecResult result =
      ExecSql("SELECT name FROM sqlite_master WHERE type = 'table';",
              GetAllTableNamesCallback, &all_table_names);
  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to get all table names: " << result.error_msg;
    return false;
  }

  base::Time expired_timestamp = base::Time::Now() - example_ttl;
  int error_count = 0;
  for (const auto& table_name : all_table_names) {
    // "sqlite_*" are sqlite reserved table names.
    if (table_name.find("sqlite_") == 0)
      continue;

    const ExecResult result = ExecSql(base::StringPrintf(
        "DELETE FROM '%s' WHERE timestamp < %" PRId64 ";", table_name.c_str(),
        expired_timestamp.InMillisecondsSinceUnixEpoch()));
    if (result.code != SQLITE_OK) {
      error_count++;
      LOG(ERROR) << "Failed to delete expired examples from table "
                 << table_name << "with message: " << result.error_msg;
    } else {
      DVLOG(1) << "Delete expired examples from table " << table_name
               << " count = " << sqlite3_changes(db_.get());
    }
  }
  return error_count == 0;
}

std::optional<MetaRecord> ExampleDatabase::GetMetaRecord(
    const std::string& identifier) const {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to get last used example id in a closed database";
    return std::nullopt;
  }

  // Uses prepared stmt instead of a simple ExecSql because stmt returns
  // SQLITE_DONE explicitly when there are no matching records, while ExecSql
  // just returns SQLITE_OK anyway.
  sqlite3_stmt* stmt = nullptr;
  const std::string sql = base::StringPrintf(
      "SELECT last_used_example_id, last_used_example_timestamp, timestamp "
      "FROM '%s' WHERE identifier = '%s';",
      kMetaTableName, identifier.c_str());
  int sqlite_code =
      sqlite3_prepare_v2(db_.get(), sql.c_str(), -1, &stmt, nullptr);

  if (sqlite_code != SQLITE_OK) {
    LOG(ERROR) << "Couldn't compile SELECT statement: "
               << sqlite3_errmsg(db_.get());
    return std::nullopt;
  }

  std::optional<MetaRecord> result;
  sqlite_code = sqlite3_step(stmt);
  if (sqlite_code == SQLITE_ROW) {
    MetaRecord record;
    record.last_used_example_id = sqlite3_column_int64(stmt, 0);
    record.last_used_example_timestamp =
        base::Time::FromMillisecondsSinceUnixEpoch(
            sqlite3_column_int64(stmt, 1));
    record.timestamp = base::Time::FromMillisecondsSinceUnixEpoch(
        sqlite3_column_int64(stmt, 2));
    result = std::move(record);
  } else if (sqlite_code == SQLITE_DONE) {
    DVLOG(1) << "Metatable doesn't have record for identifier = " << identifier;
  } else {  // This is unexpected, logs an error.
    LOG(ERROR) << "Failed to retrieve last_used_example_id for identifier = "
               << identifier;
  }

  sqlite3_finalize(stmt);

  return result;
}

bool ExampleDatabase::UpdateMetaRecord(
    const std::string& identifier, const MetaRecord& new_meta_record) const {
  DCHECK_GE(new_meta_record.last_used_example_id, 0);
  DCHECK_GE(new_meta_record.last_used_example_timestamp,
            base::Time::UnixEpoch());
  DCHECK_GE(new_meta_record.timestamp, base::Time::UnixEpoch());

  const std::string sql = base::StringPrintf(
      "INSERT INTO '%s' (identifier, last_used_example_id, "
      "last_used_example_timestamp, timestamp) VALUES("
      "'%s', %" PRId64 ", %" PRId64 ", %" PRId64
      ") ON CONFLICT(identifier) DO UPDATE SET "
      "last_used_example_id=excluded.last_used_example_id, "
      "last_used_example_timestamp=excluded.last_used_example_timestamp, "
      "timestamp=excluded.timestamp;",
      kMetaTableName, identifier.c_str(), new_meta_record.last_used_example_id,
      new_meta_record.last_used_example_timestamp
          .InMillisecondsSinceUnixEpoch(),
      new_meta_record.timestamp.InMillisecondsSinceUnixEpoch());

  ExecResult result = ExecSql(sql);
  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to update last_used_example_id for identifier: "
               << identifier << " with error message:" << result.error_msg;
    return false;
  }

  return true;
}

ExampleDatabase::Iterator ExampleDatabase::GetIterator(
    const std::string& table_name,
    const base::Time& start_time,
    const base::Time& end_time,
    bool descending,
    const size_t limit) const {
  return Iterator(db_.get(), table_name, start_time, end_time, descending,
                  limit);
}

ExampleDatabase::Iterator ExampleDatabase::GetIteratorForTesting(
    const std::string& table_name) const {
  return Iterator(db_.get(), table_name);
}

bool ExampleDatabase::InsertExample(const std::string& table_name,
                                    const ExampleRecord& example_record) {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to insert example into a closed database";
    return false;
  }

  // Compile the insertion statement.
  sqlite3_stmt* stmt = nullptr;
  const std::string sql_code =
      base::StringPrintf("INSERT INTO '%s' (example, timestamp) VALUES (?, ?);",
                         table_name.c_str());
  const int result =
      sqlite3_prepare_v2(db_.get(), sql_code.c_str(), -1, &stmt, nullptr);
  if (result != SQLITE_OK) {
    LOG(ERROR) << "Couldn't compile insertion statement: "
               << sqlite3_errmsg(db_.get());
    return false;
  }

  // Run the insertion statement.
  const bool ok =
      sqlite3_bind_blob(stmt, 1, example_record.serialized_example.c_str(),
                        example_record.serialized_example.length(),
                        nullptr) == SQLITE_OK &&
      sqlite3_bind_int64(
          stmt, 2, example_record.timestamp.InMillisecondsSinceUnixEpoch()) ==
          SQLITE_OK &&
      sqlite3_step(stmt) == SQLITE_DONE;
  sqlite3_finalize(stmt);

  if (!ok) {
    LOG(ERROR) << "Failed to insert example: " << sqlite3_errmsg(db_.get());
  }
  DVLOG(1) << "Insert example for client " << table_name;
  return ok;
}

void ExampleDatabase::DeleteAllExamples(const std::string& table_name) {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to delete from a closed database";
    return;
  }

  const ExecResult result =
      ExecSql(base::StringPrintf("DELETE FROM '%s';", table_name.c_str()));
  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to delete examples: " << result.error_msg;
  }
}

bool ExampleDatabase::TableExists(const std::string& table_name) const {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to query table of a closed database";
    return false;
  }

  int table_count = 0;
  const std::string sql_code = base::StringPrintf(
      "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = "
      "'%s';",
      table_name.c_str());
  ExecResult result = ExecSql(sql_code, TableExistsCallback, &table_count);

  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to query table existence: " << result.error_msg;
    return false;
  }

  if (table_count <= 0)
    return false;

  DCHECK(table_count == 1) << "There should be only one table with name '"
                           << table_name << "'";

  return true;
}

bool ExampleDatabase::CreateClientTable(const std::string& table_name) {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to create table in a closed database";
    return false;
  }

  const std::string sql = base::StringPrintf(R"(
      CREATE TABLE '%s' (
        id         INTEGER PRIMARY KEY AUTOINCREMENT
                           NOT NULL,
        example    BLOB    NOT NULL,
        timestamp  INTEGER NOT NULL
      ))",
                                             table_name.c_str());
  const ExecResult result = ExecSql(sql);
  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to create table: " << result.error_msg;
    return false;
  }
  return true;
}

bool ExampleDatabase::MetaTableExists() const {
  return TableExists(std::string(kMetaTableName));
}

bool ExampleDatabase::CreateMetaTable() {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to create table in a closed database";
    return false;
  }

  const std::string sql = base::StringPrintf(
      "CREATE TABLE '%s' ("
      " identifier                    TEXT PRIMARY KEY NOT NULL,"
      " last_used_example_id          INTEGER NOT NULL,"
      " last_used_example_timestamp   INTEGER NOT NULL,"
      " timestamp                     INTEGER NOT NULL"
      ")",
      kMetaTableName);
  const ExecResult result = ExecSql(sql);
  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to create table: " << result.error_msg;
    return false;
  }
  return true;
}

int ExampleDatabase::ExampleCount(const std::string& table_name,
                                  const base::Time& start_time,
                                  const base::Time& end_time) const {
  DCHECK(start_time != base::Time() && end_time != base::Time())
      << "start_time and end_time cannot be zero values";
  return ExampleCountInternal(table_name,
                              MaybeWhereClause(start_time, end_time));
}

int ExampleDatabase::ExampleCountForTesting(
    const std::string& table_name) const {
  return ExampleCountInternal(table_name, /* where_clause = */
                              std::string());
}

int ExampleDatabase::ExampleCountInternal(
    const std::string& table_name, const std::string& where_clause) const {
  if (!IsOpen()) {
    LOG(ERROR) << "Trying to count examples in a closed database";
    return 0;
  }

  int count = 0;
  const ExecResult result =
      ExecSql(base::StringPrintf("SELECT COUNT(*) FROM '%s' %s;",
                                 table_name.c_str(), where_clause.c_str()),
              ExampleCountCallback, &count);

  if (result.code != SQLITE_OK) {
    LOG(ERROR) << "Failed to count examples: " << result.error_msg;
    return 0;
  }
  return count;
}

ExampleDatabase::ExecResult ExampleDatabase::ExecSql(
    const std::string& sql) const {
  return ExecSql(sql, nullptr, nullptr);
}

ExampleDatabase::ExecResult ExampleDatabase::ExecSql(const std::string& sql,
                                                     SqliteCallback callback,
                                                     void* const data) const {
  char* error_msg = nullptr;
  const int result =
      sqlite3_exec(db_.get(), sql.c_str(), callback, data, &error_msg);
  // According to sqlite3_exec() documentation, error_msg points to memory
  // allocated by sqlite3_malloc(), which must be freed by sqlite3_free().
  std::string error_msg_str;
  if (error_msg) {
    error_msg_str.assign(error_msg);
    sqlite3_free(error_msg);
  }
  return {result, error_msg_str};
}

}  // namespace federated
