// 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 <stddef.h>

#include <memory>
#include <vector>

#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_task_runner_handle.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_bundle.h"
#include "content/public/test/test_utils.h"
#include "sql/statement.h"

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

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

namespace predictors {

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

  void SetUp() override;
  void TearDown() override;

  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:
  content::TestBrowserThreadBundle thread_bundle_;
  TestingProfile profile_;
  std::unique_ptr<PredictorDatabase> db_;
};

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

AutocompleteActionPredictorTableTest::AutocompleteActionPredictorTableTest() {}

AutocompleteActionPredictorTableTest::~AutocompleteActionPredictorTableTest() {
}

void AutocompleteActionPredictorTableTest::SetUp() {
  db_ = base::MakeUnique<PredictorDatabase>(
      &profile_, base::SequencedTaskRunnerHandle::Get());
  content::RunAllTasksUntilIdle();

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

void AutocompleteActionPredictorTableTest::TearDown() {
  db_ = nullptr;
  content::RunAllTasksUntilIdle();
  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
