// Copyright 2014 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 "base/bind.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "sql/database.h"
#include "sql/statement.h"
#include "sql/test/scoped_error_expecter.h"
#include "storage/browser/database/databases_table.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"

using base::ASCIIToUTF16;
using storage::DatabaseDetails;
using storage::DatabasesTable;

namespace content {

static void CheckDetailsAreEqual(const DatabaseDetails& d1,
                                 const DatabaseDetails& d2) {
  EXPECT_EQ(d1.origin_identifier, d2.origin_identifier);
  EXPECT_EQ(d1.database_name, d2.database_name);
  EXPECT_EQ(d1.description, d2.description);
  EXPECT_EQ(d1.estimated_size, d2.estimated_size);
}

static bool DatabasesTableIsEmpty(sql::Database* db) {
  sql::Statement statement(
      db->GetCachedStatement(SQL_FROM_HERE, "SELECT COUNT(*) FROM Databases"));
  return (statement.is_valid() && statement.Step() && !statement.ColumnInt(0));
}

TEST(DatabasesTableTest, TestIt) {
  // Initialize the 'Databases' table.
  sql::Database db;

  sql::test::ScopedErrorExpecter expecter;
  // TODO(shess): Suppressing SQLITE_CONSTRAINT because the code
  // expects that and handles the resulting error.  Consider revising
  // the code to use INSERT OR IGNORE (which would not throw
  // SQLITE_CONSTRAINT) and then check ChangeCount() to see if any
  // changes were made.
  expecter.ExpectError(SQLITE_CONSTRAINT);

  // Initialize the temp dir and the 'Databases' table.
  EXPECT_TRUE(db.OpenInMemory());
  DatabasesTable databases_table(&db);
  EXPECT_TRUE(databases_table.Init());

  // The 'Databases' table should be empty.
  EXPECT_TRUE(DatabasesTableIsEmpty(&db));

  // Create the details for a databases.
  DatabaseDetails details_in1;
  DatabaseDetails details_out1;
  details_in1.origin_identifier = "origin1";
  details_in1.database_name = ASCIIToUTF16("db1");
  details_in1.description = ASCIIToUTF16("description_db1");
  details_in1.estimated_size = 100;

  // Updating details for this database should fail.
  EXPECT_FALSE(databases_table.UpdateDatabaseDetails(details_in1));
  EXPECT_FALSE(databases_table.GetDatabaseDetails(
      details_in1.origin_identifier, details_in1.database_name, &details_out1));

  // Inserting details for this database should pass.
  EXPECT_TRUE(databases_table.InsertDatabaseDetails(details_in1));
  EXPECT_TRUE(databases_table.GetDatabaseDetails(
      details_in1.origin_identifier, details_in1.database_name, &details_out1));
  EXPECT_EQ(1, databases_table.GetDatabaseID(details_in1.origin_identifier,
                                             details_in1.database_name));

  // Check that the details were correctly written to the database.
  CheckDetailsAreEqual(details_in1, details_out1);

  // Check that inserting a duplicate row fails.
  EXPECT_FALSE(databases_table.InsertDatabaseDetails(details_in1));

  // Insert details for another database with the same origin.
  DatabaseDetails details_in2;
  details_in2.origin_identifier = "origin1";
  details_in2.database_name = ASCIIToUTF16("db2");
  details_in2.description = ASCIIToUTF16("description_db2");
  details_in2.estimated_size = 200;
  EXPECT_TRUE(databases_table.InsertDatabaseDetails(details_in2));
  EXPECT_EQ(2, databases_table.GetDatabaseID(details_in2.origin_identifier,
                                             details_in2.database_name));

  // Insert details for a third database with a different origin.
  DatabaseDetails details_in3;
  details_in3.origin_identifier = "origin2";
  details_in3.database_name = ASCIIToUTF16("db3");
  details_in3.description = ASCIIToUTF16("description_db3");
  details_in3.estimated_size = 300;
  EXPECT_TRUE(databases_table.InsertDatabaseDetails(details_in3));
  EXPECT_EQ(3, databases_table.GetDatabaseID(details_in3.origin_identifier,
                                             details_in3.database_name));

  // There should be no database with origin "origin3".
  std::vector<DatabaseDetails> details_out_origin3;
  EXPECT_TRUE(databases_table.GetAllDatabaseDetailsForOriginIdentifier(
      "origin3", &details_out_origin3));
  EXPECT_TRUE(details_out_origin3.empty());

  // There should be only two databases with origin "origin1".
  std::vector<DatabaseDetails> details_out_origin1;
  EXPECT_TRUE(databases_table.GetAllDatabaseDetailsForOriginIdentifier(
      details_in1.origin_identifier, &details_out_origin1));
  EXPECT_EQ(size_t(2), details_out_origin1.size());
  CheckDetailsAreEqual(details_in1, details_out_origin1[0]);
  CheckDetailsAreEqual(details_in2, details_out_origin1[1]);

  // Get the list of all origins: should be "origin1" and "origin2".
  std::vector<std::string> origins_out;
  EXPECT_TRUE(databases_table.GetAllOriginIdentifiers(&origins_out));
  EXPECT_EQ(size_t(2), origins_out.size());
  EXPECT_EQ(details_in1.origin_identifier, origins_out[0]);
  EXPECT_EQ(details_in3.origin_identifier, origins_out[1]);

  // Delete an origin and check that it's no longer in the table.
  origins_out.clear();
  EXPECT_TRUE(
      databases_table.DeleteOriginIdentifier(details_in3.origin_identifier));
  EXPECT_TRUE(databases_table.GetAllOriginIdentifiers(&origins_out));
  EXPECT_EQ(size_t(1), origins_out.size());
  EXPECT_EQ(details_in1.origin_identifier, origins_out[0]);

  // Deleting an origin that doesn't have any record in this table should fail.
  EXPECT_FALSE(databases_table.DeleteOriginIdentifier("unknown_origin"));

  // Delete the details for 'db1' and check that they're no longer there.
  EXPECT_TRUE(databases_table.DeleteDatabaseDetails(
      details_in1.origin_identifier, details_in1.database_name));
  EXPECT_FALSE(databases_table.GetDatabaseDetails(
      details_in1.origin_identifier, details_in1.database_name, &details_out1));

  // Check that trying to delete a record that doesn't exist fails.
  EXPECT_FALSE(databases_table.DeleteDatabaseDetails(
      "unknown_origin", ASCIIToUTF16("unknown_database")));

  ASSERT_TRUE(expecter.SawExpectedErrors());
}

}  // namespace content
