// 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 <vector>

#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/predictors/autocomplete_action_predictor_table.h"
#include "chrome/browser/predictors/predictor_database.h"
#include "chrome/browser/predictors/predictor_database_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread.h"
#include "sql/statement.h"

#include "testing/gtest/include/gtest/gtest.h"

using base::Time;
using base::TimeDelta;
using content::BrowserThread;
using predictors::AutocompleteActionPredictorTable;

namespace predictors {

class AutocompleteActionPredictorTableTest : public testing::Test {
 public:
  AutocompleteActionPredictorTableTest();
  virtual ~AutocompleteActionPredictorTableTest();

  virtual void SetUp();
  virtual void TearDown();

  size_t CountRecords() const;

  void AddAll();

  bool RowsAreEqual(const AutocompleteActionPredictorTable::Row& lhs,
                    const AutocompleteActionPredictorTable::Row& rhs) const;

  TestingProfile* profile() { return &profile_; }

 protected:

  // Test functions that can be run against this text fixture or
  // AutocompleteActionPredictorTableReopenTest that inherits from this.
  void TestGetRow();
  void TestAddAndUpdateRows();
  void TestDeleteRows();
  void TestDeleteAllRows();

  AutocompleteActionPredictorTable::Rows test_db_;

 private:
  TestingProfile profile_;
  scoped_ptr<PredictorDatabase> db_;
  base::MessageLoop loop_;
  content::TestBrowserThread db_thread_;
};

class AutocompleteActionPredictorTableReopenTest
    : public AutocompleteActionPredictorTableTest {
 public:
  virtual void SetUp() {
    // By calling SetUp twice, we make sure that the table already exists for
    // this fixture.
    AutocompleteActionPredictorTableTest::SetUp();
    AutocompleteActionPredictorTableTest::TearDown();
    AutocompleteActionPredictorTableTest::SetUp();
  }
};

AutocompleteActionPredictorTableTest::AutocompleteActionPredictorTableTest()
    : loop_(base::MessageLoop::TYPE_DEFAULT),
      db_thread_(BrowserThread::DB, &loop_) {
}

AutocompleteActionPredictorTableTest::~AutocompleteActionPredictorTableTest() {
}

void AutocompleteActionPredictorTableTest::SetUp() {
  db_.reset(new PredictorDatabase(&profile_));
  loop_.RunUntilIdle();

  test_db_.push_back(AutocompleteActionPredictorTable::Row(
      "BD85DBA2-8C29-49F9-84AE-48E1E90880DF",
      ASCIIToUTF16("goog"), GURL("http://www.google.com/"),
      1, 0));
  test_db_.push_back(AutocompleteActionPredictorTable::Row(
      "BD85DBA2-8C29-49F9-84AE-48E1E90880E0",
      ASCIIToUTF16("slash"), GURL("http://slashdot.org/"),
      3, 2));
  test_db_.push_back(AutocompleteActionPredictorTable::Row(
      "BD85DBA2-8C29-49F9-84AE-48E1E90880E1",
      ASCIIToUTF16("news"), GURL("http://slashdot.org/"),
      0, 1));
}

void AutocompleteActionPredictorTableTest::TearDown() {
  db_.reset(NULL);
  loop_.RunUntilIdle();
  test_db_.clear();
}

size_t AutocompleteActionPredictorTableTest::CountRecords() const {
  sql::Statement s(db_->GetDatabase()->GetUniqueStatement(
      "SELECT count(*) FROM network_action_predictor"));
  EXPECT_TRUE(s.Step());
  return static_cast<size_t>(s.ColumnInt(0));
}

void AutocompleteActionPredictorTableTest::AddAll() {
  db_->autocomplete_table()->AddAndUpdateRows(
      test_db_, AutocompleteActionPredictorTable::Rows());

  EXPECT_EQ(test_db_.size(), CountRecords());
}

bool AutocompleteActionPredictorTableTest::RowsAreEqual(
    const AutocompleteActionPredictorTable::Row& lhs,
    const AutocompleteActionPredictorTable::Row& rhs) const {
  return (lhs.id == rhs.id &&
          lhs.user_text == rhs.user_text &&
          lhs.url == rhs.url &&
          lhs.number_of_hits == rhs.number_of_hits &&
          lhs.number_of_misses == rhs.number_of_misses);
}

void AutocompleteActionPredictorTableTest::TestGetRow() {
  db_->autocomplete_table()->AddAndUpdateRows(
      AutocompleteActionPredictorTable::Rows(1, test_db_[0]),
      AutocompleteActionPredictorTable::Rows());
  AutocompleteActionPredictorTable::Row row;
  db_->autocomplete_table()->GetRow(test_db_[0].id, &row);
  EXPECT_TRUE(RowsAreEqual(test_db_[0], row))
      << "Expected: Row with id " << test_db_[0].id << "\n"
      << "Got:      Row with id " << row.id;
}

void AutocompleteActionPredictorTableTest::TestAddAndUpdateRows() {
  EXPECT_EQ(0U, CountRecords());

  AutocompleteActionPredictorTable::Rows rows_to_add;
  rows_to_add.push_back(test_db_[0]);
  rows_to_add.push_back(test_db_[1]);
  db_->autocomplete_table()->AddAndUpdateRows(
      rows_to_add,
      AutocompleteActionPredictorTable::Rows());
  EXPECT_EQ(2U, CountRecords());

  AutocompleteActionPredictorTable::Row row1 = test_db_[1];
  row1.number_of_hits = row1.number_of_hits + 1;
  db_->autocomplete_table()->AddAndUpdateRows(
      AutocompleteActionPredictorTable::Rows(1, test_db_[2]),
      AutocompleteActionPredictorTable::Rows(1, row1));
  EXPECT_EQ(3U, CountRecords());

  AutocompleteActionPredictorTable::Row updated_row1;
  db_->autocomplete_table()->GetRow(test_db_[1].id, &updated_row1);
  EXPECT_TRUE(RowsAreEqual(row1, updated_row1))
      << "Expected: Row with id " << row1.id << "\n"
      << "Got:      Row with id " << updated_row1.id;

  AutocompleteActionPredictorTable::Row row0 = test_db_[0];
  row0.number_of_hits = row0.number_of_hits + 2;
  AutocompleteActionPredictorTable::Row row2 = test_db_[2];
  row2.number_of_hits = row2.number_of_hits + 2;
  AutocompleteActionPredictorTable::Rows rows_to_update;
  rows_to_update.push_back(row0);
  rows_to_update.push_back(row2);
  db_->autocomplete_table()->AddAndUpdateRows(
      AutocompleteActionPredictorTable::Rows(),
      rows_to_update);
  EXPECT_EQ(3U, CountRecords());

  AutocompleteActionPredictorTable::Row updated_row0, updated_row2;
  db_->autocomplete_table()->GetRow(test_db_[0].id, &updated_row0);
  db_->autocomplete_table()->GetRow(test_db_[2].id, &updated_row2);
  EXPECT_TRUE(RowsAreEqual(row0, updated_row0))
      << "Expected: Row with id " << row0.id << "\n"
      << "Got:      Row with id " << updated_row0.id;
  EXPECT_TRUE(RowsAreEqual(row2, updated_row2))
      << "Expected: Row with id " << row2.id << "\n"
      << "Got:      Row with id " << updated_row2.id;
}

void AutocompleteActionPredictorTableTest::TestDeleteRows() {
  AddAll();
  std::vector<AutocompleteActionPredictorTable::Row::Id> id_list;
  id_list.push_back(test_db_[0].id);
  id_list.push_back(test_db_[2].id);
  db_->autocomplete_table()->DeleteRows(id_list);
  EXPECT_EQ(test_db_.size() - 2, CountRecords());

  AutocompleteActionPredictorTable::Row row;
  db_->autocomplete_table()->GetRow(test_db_[1].id, &row);
  EXPECT_TRUE(RowsAreEqual(test_db_[1], row));
}

void AutocompleteActionPredictorTableTest::TestDeleteAllRows() {
  AddAll();
  db_->autocomplete_table()->DeleteAllRows();
  EXPECT_EQ(0U, CountRecords());
}

// AutocompleteActionPredictorTableTest tests
TEST_F(AutocompleteActionPredictorTableTest, GetRow) {
  TestGetRow();
}

TEST_F(AutocompleteActionPredictorTableTest, AddAndUpdateRows) {
  TestAddAndUpdateRows();
}

TEST_F(AutocompleteActionPredictorTableTest, DeleteRows) {
  TestDeleteRows();
}

TEST_F(AutocompleteActionPredictorTableTest, DeleteAllRows) {
  TestDeleteAllRows();
}

// AutocompleteActionPredictorTableReopenTest tests
TEST_F(AutocompleteActionPredictorTableReopenTest, GetRow) {
  TestGetRow();
}

TEST_F(AutocompleteActionPredictorTableReopenTest, AddAndUpdateRows) {
  TestAddAndUpdateRows();
}

TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteRows) {
  TestDeleteRows();
}

TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteAllRows) {
  TestDeleteAllRows();
}

}  // namespace predictors
