// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/permissions/permission_auditing_database.h"

#include <algorithm>
#include <iostream>
#include <limits>
#include <memory>
#include <string>
#include <vector>

#include "base/check.h"
#include "base/files/file_path.h"
#include "sql/database.h"
#include "sql/meta_table.h"
#include "sql/statement.h"
#include "sql/transaction.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"

namespace permissions {

namespace {

// For this database, schema migration is supported for at least 1 year.
// This means we can deprecate old versions that landed more than a year ago.
//
// Version 1: https://crrev.com/c/2435307 - 2020-11-04

// The current number of the database schema.
constexpr int kVersion = 1;

// The lowest version of the database schema such that a legacy code can still
// read/write the current database.
constexpr int kCompatibleVersion = 1;

}  // namespace

PermissionAuditingDatabase::PermissionAuditingDatabase() = default;

PermissionAuditingDatabase::~PermissionAuditingDatabase() = default;

bool PermissionAuditingDatabase::Init(const base::FilePath& path) {
  db_.set_histogram_tag("Permission Auditing Logs");
  if (!db_.Open(path)) {
    return false;
  }
  sql::MetaTable metatable;
  if (!metatable.Init(&db_, kVersion, kCompatibleVersion)) {
    db_.Poison();
    return false;
  }
  if (metatable.GetCompatibleVersionNumber() > kVersion) {
    db_.Poison();
    return false;
  }
  if (!db_.DoesTableExist("uses")) {
    if (!CreateSchema()) {
      db_.Poison();
      return false;
    }
  }
  // TODO(anyone): perform migration if metatable.GetVersionNumber() < kVersion
  return true;
}

bool PermissionAuditingDatabase::CreateSchema() {
  sql::Transaction transaction(&db_);
  if (!transaction.Begin()) {
    return false;
  }
  if (!db_.Execute("CREATE TABLE uses("
                   "  id INTEGER PRIMARY KEY AUTOINCREMENT,"
                   "  origin TEXT NOT NULL,"
                   "  content_setting_type INTEGER NOT NULL,"
                   "  usage_start_time INTEGER NOT NULL,"
                   "  usage_end_time INTEGER NOT NULL,"
                   "  had_user_activation INTEGER NOT NULL,"
                   "  was_foreground INTEGER NOT NULL,"
                   "  had_focus INTEGER NOT NULL"
                   ")")) {
    return false;
  }
  if (!db_.Execute("CREATE UNIQUE INDEX setting_origin_start_time ON "
                   "uses(origin, content_setting_type,"
                   "usage_start_time)")) {
    return false;
  }
  if (!db_.Execute("CREATE INDEX setting_origin_end_time ON "
                   "uses(origin, content_setting_type,"
                   "usage_end_time)")) {
    return false;
  }
  if (!db_.Execute("CREATE INDEX start_time ON "
                   "uses(usage_start_time)")) {
    return false;
  }
  if (!db_.Execute("CREATE INDEX end_time ON "
                   "uses(usage_end_time)")) {
    return false;
  }
  return transaction.Commit();
}

bool PermissionAuditingDatabase::StorePermissionUsage(
    const PermissionUsageSession& session) {
  DCHECK(session.IsValid());
  sql::Statement statement(
      db_.GetCachedStatement(SQL_FROM_HERE,
                             "INSERT INTO uses(origin, content_setting_type,"
                             "usage_start_time, usage_end_time,"
                             "had_user_activation, was_foreground, had_focus)"
                             "VALUES (?, ?, ?, ?, ?, ?, ?)"));
  statement.BindString(0, session.origin.Serialize());
  statement.BindInt(1, static_cast<int32_t>(session.type));
  statement.BindTime(2, session.usage_start);
  statement.BindTime(3, session.usage_end);
  statement.BindBool(4, session.had_user_activation);
  statement.BindBool(5, session.was_foreground);
  statement.BindBool(6, session.had_focus);

  sql::Transaction transaction(&db_);
  if (!transaction.Begin()) {
    return false;
  }
  if (!statement.Run()) {
    return false;
  }
  return transaction.Commit();
}

std::vector<PermissionUsageSession>
PermissionAuditingDatabase::GetPermissionUsageHistory(ContentSettingsType type,
                                                      const url::Origin& origin,
                                                      base::Time start_time) {
  DCHECK(!origin.opaque());
  std::vector<PermissionUsageSession> sessions;
  sql::Statement statement(db_.GetCachedStatement(
      SQL_FROM_HERE,
      "SELECT usage_start_time, usage_end_time, had_user_activation,"
      "was_foreground, had_focus "
      "FROM uses "
      "WHERE origin = ? AND content_setting_type = ? "
      "AND usage_end_time >= ?"));
  statement.BindString(0, origin.Serialize());
  statement.BindInt(1, static_cast<int32_t>(type));
  statement.BindTime(2, start_time.is_null() ? base::Time::Min() : start_time);

  while (statement.Step()) {
    sessions.push_back({.origin = origin,
                        .type = type,
                        .usage_start = statement.ColumnTime(0),
                        .usage_end = statement.ColumnTime(1),
                        .had_user_activation = statement.ColumnBool(2),
                        .was_foreground = statement.ColumnBool(3),
                        .had_focus = statement.ColumnBool(4)});
  }
  return sessions;
}

absl::optional<base::Time>
PermissionAuditingDatabase::GetLastPermissionUsageTime(
    ContentSettingsType type,
    const url::Origin& origin) {
  DCHECK(!origin.opaque());
  sql::Statement statement(
      db_.GetCachedStatement(SQL_FROM_HERE,
                             "SELECT usage_end_time "
                             "FROM uses "
                             "WHERE origin = ? AND content_setting_type = ? "
                             "ORDER BY usage_end_time DESC "
                             "LIMIT 1"));
  statement.BindString(0, origin.Serialize());
  statement.BindInt(1, static_cast<int32_t>(type));
  absl::optional<base::Time> last_usage;
  if (statement.Step()) {
    last_usage = statement.ColumnTime(0);
  }
  return last_usage;
}

bool PermissionAuditingDatabase::UpdateEndTime(ContentSettingsType type,
                                               const url::Origin& origin,
                                               base::Time start_time,
                                               base::Time new_end_time) {
  DCHECK(!origin.opaque());
  DCHECK(!start_time.is_null());
  DCHECK(!new_end_time.is_null());
  DCHECK_LE(start_time, new_end_time);
  sql::Statement statement(
      db_.GetCachedStatement(SQL_FROM_HERE,
                             "UPDATE uses "
                             "SET usage_end_time = ? "
                             "WHERE origin = ? AND content_setting_type = ? "
                             "AND usage_start_time = ?"));
  statement.BindTime(0, new_end_time);
  statement.BindString(1, origin.Serialize());
  statement.BindInt(2, static_cast<int32_t>(type));
  statement.BindTime(3, start_time);

  sql::Transaction transaction(&db_);
  if (!transaction.Begin()) {
    return false;
  }
  if (!statement.Run()) {
    return false;
  }
  return transaction.Commit();
}

bool PermissionAuditingDatabase::DeleteSessionsBetween(base::Time start_time,
                                                       base::Time end_time) {
  std::vector<int> ids;
  sql::Statement statement(
      db_.GetCachedStatement(SQL_FROM_HERE,
                             "DELETE FROM uses "
                             "WHERE usage_start_time BETWEEN ? AND ? "
                             "OR usage_end_time BETWEEN ? AND ?"));
  statement.BindTime(0, start_time.is_null() ? base::Time::Min() : start_time);
  statement.BindTime(1, end_time.is_null() ? base::Time::Max() : end_time);
  statement.BindTime(2, start_time.is_null() ? base::Time::Min() : start_time);
  statement.BindTime(3, end_time.is_null() ? base::Time::Max() : end_time);

  sql::Transaction transaction(&db_);
  if (!transaction.Begin()) {
    return false;
  }
  if (!statement.Run()) {
    return false;
  }
  return transaction.Commit();
}

}  // namespace permissions
