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

#include "components/webdata/common/web_database_backend.h"

#include <algorithm>
#include <utility>

#include "base/check.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/task/sequenced_task_runner.h"
#include "components/os_crypt/async/common/encryptor.h"
#include "components/webdata/common/web_data_request_manager.h"
#include "components/webdata/common/web_database.h"
#include "components/webdata/common/web_database_table.h"
#include "sql/error_delegate_util.h"
#include "sql/sqlite_result_code.h"

WebDatabaseBackend::WebDatabaseBackend(
    const base::FilePath& path,
    std::unique_ptr<Delegate> delegate,
    const scoped_refptr<base::SequencedTaskRunner>& db_thread)
    : base::RefCountedDeleteOnSequence<WebDatabaseBackend>(db_thread),
      db_path_(path),
      delegate_(std::move(delegate)) {
  // WebDatabaseBackend is created on the client sequence then accessed on the
  // DB sequence.
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

void WebDatabaseBackend::AddTable(std::unique_ptr<WebDatabaseTable> table) {
  CHECK(!init_complete_) << "AddTable must be called before init starts.";
  tables_.push_back(std::move(table));
}

void WebDatabaseBackend::MaybeInitEncryptorOnUiSequence(
    os_crypt_async::Encryptor encryptor) {
  CHECK(!encryptor_) << "Init should only be called once.";
  // Encryptor is thread safe. This transfers it from the UI sequence to the DB
  // sequence. The CHECKs above and below guarantee this only happens once,
  // before any tasks have been posted to the DB sequence.
  encryptor_.emplace(std::move(encryptor));
}

void WebDatabaseBackend::InitDatabase() {
  // MaybeInitEncryptorOnUiSequence must be called first.
  CHECK(encryptor_);
  LoadDatabaseIfNecessary();
  if (delegate_) {
    delegate_->DBLoaded(init_status_, diagnostics_);
  }
}

void WebDatabaseBackend::ShutdownDatabase() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (db_ && init_status_ == sql::INIT_OK) {
    db_->CommitTransaction();
  }
  db_.reset();
  init_complete_ = true;  // Ensures the init sequence is not re-run.
  init_status_ = sql::INIT_FAILURE;
}

void WebDatabaseBackend::DBWriteTaskWrapper(
    WebDatabaseService::WriteTask task,
    std::unique_ptr<WebDataRequest> request) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(init_complete_) << "Init must be complete before running a DB task.";
  if (!request->IsActive()) {
    return;
  }
  ExecuteWriteTask(std::move(task));
  request_manager_->RequestCompleted(std::move(request), nullptr);
}

void WebDatabaseBackend::ExecuteWriteTask(WebDatabaseService::WriteTask task) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(init_complete_) << "Init must be complete before running a DB task.";
  // The database is not opened or have been shutdown.
  if (!db_) {
    return;
  }

  auto transaction = database()->AcquireTransaction();
  if (init_status_ == sql::INIT_OK) {
    WebDatabase::State state = std::move(task).Run(db_.get());
    if (state == WebDatabase::COMMIT_NEEDED) {
      // Either commit the changes using the Commit(...) call or commit the
      // changes via the scoped transaction. This is controlled through the
      // Finch experiment 'SqlScopedTransactionWebDatabase'.
      Commit();
      if (transaction) {
        transaction->Commit();
      }
    }
  }
}

void WebDatabaseBackend::DBReadTaskWrapper(
    WebDatabaseService::ReadTask task,
    std::unique_ptr<WebDataRequest> request) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(init_complete_) << "Init must be complete before running a DB task.";
  if (!request->IsActive()) {
    return;
  }
  std::unique_ptr<WDTypedResult> result = ExecuteReadTask(std::move(task));
  request_manager_->RequestCompleted(std::move(request), std::move(result));
}

std::unique_ptr<WDTypedResult> WebDatabaseBackend::ExecuteReadTask(
    WebDatabaseService::ReadTask task) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(init_complete_) << "Init must be complete before running a DB task.";
  return (db_ && init_status_ == sql::INIT_OK) ? std::move(task).Run(db_.get())
                                               : nullptr;
}

WebDatabaseBackend::~WebDatabaseBackend() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  ShutdownDatabase();
}

void WebDatabaseBackend::LoadDatabaseIfNecessary() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (init_complete_ || db_path_.empty()) {
    return;
  }

  init_complete_ = true;
  db_ = std::make_unique<WebDatabase>();

  for (const auto& table : tables_) {
    db_->AddTable(table.get());
  }

  // Unretained to avoid a ref loop since we own |db_|.
  db_->set_error_callback(base::BindRepeating(
      &WebDatabaseBackend::DatabaseErrorCallback, base::Unretained(this)));
  diagnostics_.clear();
  catastrophic_error_occurred_ = false;
  init_status_ = db_->Init(db_path_, &(*encryptor_));

  if (init_status_ != sql::INIT_OK) {
    // The database failed to be opened. This can be caused by a third-party
    // that locks or has an exclusive sql query running. In that scenario,
    // the initial error code is stored in `init_status_` and
    // `catastrophic_error_occurred_` to ensure the user is getting the window
    // notification about the profile being corrupt.
    //
    // Since Chrome keeps running after the error windows, we do mitigate the
    // assumption of the WebDatabase not being null by opening an in-memory
    // and empty database.
    db_->GetSQLConnection()->Close();
    sql::InitStatus memory_init_status =
        db_->Init(base::FilePath(WebDatabase::kInMemoryPath), &(*encryptor_));
    CHECK_EQ(memory_init_status, sql::INIT_OK);
  }

  DCHECK(db_->GetSQLConnection());
  DCHECK(db_->GetSQLConnection()->is_open());

  // A catastrophic error might have happened and recovered.
  if (catastrophic_error_occurred_) {
    init_status_ = sql::INIT_OK_WITH_DATA_LOSS;
  }
  db_->BeginTransaction();
}

void WebDatabaseBackend::DatabaseErrorCallback(int error,
                                               sql::Statement* statement) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  sql::UmaHistogramSqliteResult("WebDatabase.DatabaseErrors", error);

  // We ignore any further error callbacks after the first catastrophic error.
  if (!catastrophic_error_occurred_ && sql::IsErrorCatastrophic(error)) {
    catastrophic_error_occurred_ = true;
    diagnostics_.clear();
    // If the error is triggered during the call to Database::Open(...), it is
    // possible that the database is not opened (https://crbug.com/420369590).
    // The call to GetDiagnosticInfo(...) will execute sql statements; which is
    // invalid on a closed database.
    if (db_->GetSQLConnection()->is_open()) {
      diagnostics_ += db_->GetDiagnosticInfo(error, statement);
    }
    diagnostics_ += sql::GetCorruptFileDiagnosticsInfo(db_path_);

    db_->GetSQLConnection()->RazeAndPoison();
  }
}

void WebDatabaseBackend::Commit() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(db_);
  DCHECK_EQ(sql::INIT_OK, init_status_);
  db_->CommitTransaction();
  db_->BeginTransaction();
}
