// Copyright (c) 2012 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 "chrome/browser/predictors/predictor_database.h"

#include <cstdint>
#include <memory>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/sequenced_task_runner.h"
#include "chrome/browser/predictors/autocomplete_action_predictor_table.h"
#include "chrome/browser/predictors/loading_predictor_config.h"
#include "chrome/browser/predictors/resource_prefetch_predictor.h"
#include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#include "sql/connection.h"

using content::BrowserThread;

namespace {

// TODO(shishir): This should move to a more generic name.
const base::FilePath::CharType kPredictorDatabaseName[] =
    FILE_PATH_LITERAL("Network Action Predictor");

}  // namespace

namespace predictors {

// Refcounted as it is created, initialized and destroyed on a different thread
// to the DB sequence provided to the constructor of this class that is required
// for all methods performing database access.
class PredictorDatabaseInternal
    : public base::RefCountedThreadSafe<PredictorDatabaseInternal> {
 private:
  friend class base::RefCountedThreadSafe<PredictorDatabaseInternal>;
  friend class PredictorDatabase;

  explicit PredictorDatabaseInternal(
      Profile* profile,
      scoped_refptr<base::SequencedTaskRunner> db_task_runner);
  virtual ~PredictorDatabaseInternal();

  // Opens the database file from the profile path. Separated from the
  // constructor to ease construction/destruction of this object on one thread
  // but database access on the DB sequence of |db_task_runner_|.
  void Initialize();
  void LogDatabaseStats();  //  DB sequence.

  // Cancels pending DB transactions. Should only be called on the UI thread.
  void SetCancelled();

  bool is_loading_predictor_enabled_;
  base::FilePath db_path_;
  std::unique_ptr<sql::Connection> db_;
  scoped_refptr<base::SequencedTaskRunner> db_task_runner_;

  // TODO(shishir): These tables may not need to be refcounted. Maybe move them
  // to using a WeakPtr instead.
  scoped_refptr<AutocompleteActionPredictorTable> autocomplete_table_;
  scoped_refptr<ResourcePrefetchPredictorTables> resource_prefetch_tables_;

  DISALLOW_COPY_AND_ASSIGN(PredictorDatabaseInternal);
};

PredictorDatabaseInternal::PredictorDatabaseInternal(
    Profile* profile,
    scoped_refptr<base::SequencedTaskRunner> db_task_runner)
    : db_path_(profile->GetPath().Append(kPredictorDatabaseName)),
      db_(std::make_unique<sql::Connection>()),
      db_task_runner_(db_task_runner),
      autocomplete_table_(
          new AutocompleteActionPredictorTable(db_task_runner_)),
      resource_prefetch_tables_(
          new ResourcePrefetchPredictorTables(db_task_runner_)) {
  db_->set_histogram_tag("Predictor");

  // This db does not use [meta] table, store mmap status data elsewhere.
  db_->set_mmap_alt_status();

  is_loading_predictor_enabled_ = IsLoadingPredictorEnabled(profile, nullptr);
}

PredictorDatabaseInternal::~PredictorDatabaseInternal() {
  // The connection pointer needs to be deleted on the DB sequence since there
  // might be a task in progress on the DB sequence which uses this connection.
  db_task_runner_->DeleteSoon(FROM_HERE, db_.release());
}

void PredictorDatabaseInternal::Initialize() {
  DCHECK(db_task_runner_->RunsTasksInCurrentSequence());
  // TODO(tburkard): figure out if we need this.
  //  db_->set_exclusive_locking();
  bool success = db_->Open(db_path_);

  if (!success)
    return;

  autocomplete_table_->Initialize(db_.get());
  resource_prefetch_tables_->Initialize(db_.get());

  // The logged_in_predictor table is obsolete as of Chrome 44.
  // TODO(davidben): Remove this after April 16, 2016.
  ignore_result(db_->Execute("DROP TABLE IF EXISTS logged_in_predictor"));

  LogDatabaseStats();
}

void PredictorDatabaseInternal::SetCancelled() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
         !BrowserThread::IsMessageLoopValid(BrowserThread::UI));

  autocomplete_table_->SetCancelled();
  resource_prefetch_tables_->SetCancelled();
}

void PredictorDatabaseInternal::LogDatabaseStats() {
  DCHECK(db_task_runner_->RunsTasksInCurrentSequence());

  autocomplete_table_->LogDatabaseStats();
  if (is_loading_predictor_enabled_)
    resource_prefetch_tables_->LogDatabaseStats();
}

PredictorDatabase::PredictorDatabase(
    Profile* profile,
    scoped_refptr<base::SequencedTaskRunner> db_task_runner)
    : db_(new PredictorDatabaseInternal(profile, db_task_runner)) {
  db_task_runner->PostTask(
      FROM_HERE, base::BindOnce(&PredictorDatabaseInternal::Initialize, db_));
}

PredictorDatabase::~PredictorDatabase() {
}

void PredictorDatabase::Shutdown() {
  db_->SetCancelled();
}

scoped_refptr<AutocompleteActionPredictorTable>
    PredictorDatabase::autocomplete_table() {
  return db_->autocomplete_table_;
}

scoped_refptr<ResourcePrefetchPredictorTables>
    PredictorDatabase::resource_prefetch_tables() {
  return db_->resource_prefetch_tables_;
}

sql::Connection* PredictorDatabase::GetDatabase() {
  return db_->db_.get();
}

}  // namespace predictors
