// 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 <algorithm>
#include <string>

#include "base/strings/string_util.h"
#include "chrome/browser/history/archived_database.h"
#include "sql/transaction.h"

namespace history {

namespace {

static const int kCurrentVersionNumber = 4;
static const int kCompatibleVersionNumber = 2;

}  // namespace

ArchivedDatabase::ArchivedDatabase() {
}

ArchivedDatabase::~ArchivedDatabase() {
}

bool ArchivedDatabase::Init(const base::FilePath& file_name) {
  // Set the database page size to something a little larger to give us
  // better performance (we're typically seek rather than bandwidth limited).
  // This only has an effect before any tables have been created, otherwise
  // this is a NOP. Must be a power of 2 and a max of 8192.
  db_.set_page_size(4096);

  // Don't use very much memory caching this database. We seldom use it for
  // anything important.
  db_.set_cache_size(64);

  // Run the database in exclusive mode. Nobody else should be accessing the
  // database while we're running, and this will give somewhat improved perf.
  db_.set_exclusive_locking();

  if (!db_.Open(file_name))
    return false;

  if (!InitTables()) {
    db_.Close();
    return false;
  }

  return true;
}

bool ArchivedDatabase::InitTables() {
  sql::Transaction transaction(&db_);
  if (!transaction.Begin())
    return false;

  // Version check.
  if (!meta_table_.Init(&db_, kCurrentVersionNumber,
                        kCompatibleVersionNumber))
    return false;

  // Create the tables.
  if (!CreateURLTable(false) || !InitVisitTable() ||
      !InitKeywordSearchTermsTable())
    return false;

  CreateMainURLIndex();
  CreateKeywordSearchTermsIndices();

  if (EnsureCurrentVersion() != sql::INIT_OK)
    return false;

  return transaction.Commit();
}

void ArchivedDatabase::TrimMemory(bool aggressively) {
  db_.TrimMemory(aggressively);
}

void ArchivedDatabase::BeginTransaction() {
  db_.BeginTransaction();
}

void ArchivedDatabase::CommitTransaction() {
  db_.CommitTransaction();
}

sql::Connection& ArchivedDatabase::GetDB() {
  return db_;
}

// static
int ArchivedDatabase::GetCurrentVersion() {
  return kCurrentVersionNumber;
}

// Migration -------------------------------------------------------------------

sql::InitStatus ArchivedDatabase::EnsureCurrentVersion() {
  // We can't read databases newer than we were designed for.
  if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
    LOG(WARNING) << "Archived database is too new.";
    return sql::INIT_TOO_NEW;
  }

  // NOTICE: If you are changing structures for things shared with the archived
  // history file like URLs, visits, or downloads, that will need migration as
  // well. Instead of putting such migration code in this class, it should be
  // in the corresponding file (url_database.cc, etc.) and called from here and
  // from the archived_database.cc.

  int cur_version = meta_table_.GetVersionNumber();
  if (cur_version == 1) {
    if (!DropStarredIDFromURLs()) {
      LOG(WARNING) << "Unable to update archived database to version 2.";
      return sql::INIT_FAILURE;
    }
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
    meta_table_.SetCompatibleVersionNumber(
        std::min(cur_version, kCompatibleVersionNumber));
  }

  if (cur_version == 2) {
    // This is the version prior to adding visit_source table.
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 3) {
    // This is the version prior to adding the visit_duration field in visits
    // database. We need to migrate the database.
    if (!MigrateVisitsWithoutDuration()) {
      LOG(WARNING) << "Unable to update archived database to version 4.";
      return sql::INIT_FAILURE;
    }
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  // Put future migration cases here.

  // When the version is too old, we just try to continue anyway, there should
  // not be a released product that makes a database too old for us to handle.
  LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
      "Archived database version " << cur_version << " is too old to handle.";

  return sql::INIT_OK;
}
}  // namespace history
