// Copyright 2013 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 "content/browser/dom_storage/dom_storage_database.h"

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "sql/statement.h"
#include "sql/test/scoped_error_ignorer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"

namespace content {

void CreateV1Table(sql::Connection* db) {
  ASSERT_TRUE(db->is_open());
  ASSERT_TRUE(db->Execute("DROP TABLE IF EXISTS ItemTable"));
  ASSERT_TRUE(db->Execute(
      "CREATE TABLE ItemTable ("
      "key TEXT UNIQUE ON CONFLICT REPLACE, "
      "value TEXT NOT NULL ON CONFLICT FAIL)"));
}

void CreateV2Table(sql::Connection* db) {
  ASSERT_TRUE(db->is_open());
  ASSERT_TRUE(db->Execute("DROP TABLE IF EXISTS ItemTable"));
  ASSERT_TRUE(db->Execute(
      "CREATE TABLE ItemTable ("
      "key TEXT UNIQUE ON CONFLICT REPLACE, "
      "value BLOB NOT NULL ON CONFLICT FAIL)"));
}

void CreateInvalidKeyColumnTable(sql::Connection* db) {
  // Create a table with the key type as FLOAT - this is "invalid"
  // as far as the DOM Storage db is concerned.
  ASSERT_TRUE(db->is_open());
  ASSERT_TRUE(db->Execute("DROP TABLE IF EXISTS ItemTable"));
  ASSERT_TRUE(db->Execute(
      "CREATE TABLE IF NOT EXISTS ItemTable ("
      "key FLOAT UNIQUE ON CONFLICT REPLACE, "
      "value BLOB NOT NULL ON CONFLICT FAIL)"));
}
void CreateInvalidValueColumnTable(sql::Connection* db) {
  // Create a table with the value type as FLOAT - this is "invalid"
  // as far as the DOM Storage db is concerned.
  ASSERT_TRUE(db->is_open());
  ASSERT_TRUE(db->Execute("DROP TABLE IF EXISTS ItemTable"));
  ASSERT_TRUE(db->Execute(
      "CREATE TABLE IF NOT EXISTS ItemTable ("
      "key TEXT UNIQUE ON CONFLICT REPLACE, "
      "value FLOAT NOT NULL ON CONFLICT FAIL)"));
}

void InsertDataV1(sql::Connection* db,
                  const base::string16& key,
                  const base::string16& value) {
  sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE,
      "INSERT INTO ItemTable VALUES (?,?)"));
  statement.BindString16(0, key);
  statement.BindString16(1, value);
  ASSERT_TRUE(statement.is_valid());
  statement.Run();
}

void CheckValuesMatch(DOMStorageDatabase* db,
                      const DOMStorageValuesMap& expected) {
  DOMStorageValuesMap values_read;
  db->ReadAllValues(&values_read);
  EXPECT_EQ(expected.size(), values_read.size());

  DOMStorageValuesMap::const_iterator it = values_read.begin();
  for (; it != values_read.end(); ++it) {
    base::string16 key = it->first;
    base::NullableString16 value = it->second;
    base::NullableString16 expected_value = expected.find(key)->second;
    EXPECT_EQ(expected_value.string(), value.string());
    EXPECT_EQ(expected_value.is_null(), value.is_null());
  }
}

void CreateMapWithValues(DOMStorageValuesMap* values) {
  base::string16 kCannedKeys[] = {
      ASCIIToUTF16("test"),
      ASCIIToUTF16("company"),
      ASCIIToUTF16("date"),
      ASCIIToUTF16("empty")
  };
  base::NullableString16 kCannedValues[] = {
      base::NullableString16(ASCIIToUTF16("123"), false),
      base::NullableString16(ASCIIToUTF16("Google"), false),
      base::NullableString16(ASCIIToUTF16("18-01-2012"), false),
      base::NullableString16(base::string16(), false)
  };
  for (unsigned i = 0; i < sizeof(kCannedKeys) / sizeof(kCannedKeys[0]); i++)
    (*values)[kCannedKeys[i]] = kCannedValues[i];
}

TEST(DOMStorageDatabaseTest, SimpleOpenAndClose) {
  DOMStorageDatabase db;
  EXPECT_FALSE(db.IsOpen());
  ASSERT_TRUE(db.LazyOpen(true));
  EXPECT_TRUE(db.IsOpen());
  EXPECT_EQ(DOMStorageDatabase::V2, db.DetectSchemaVersion());
  db.Close();
  EXPECT_FALSE(db.IsOpen());
}

TEST(DOMStorageDatabaseTest, CloseEmptyDatabaseDeletesFile) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath file_name =
      temp_dir.path().AppendASCII("TestDOMStorageDatabase.db");
  DOMStorageValuesMap storage;
  CreateMapWithValues(&storage);

  // First test the case that explicitly clearing the database will
  // trigger its deletion from disk.
  {
    DOMStorageDatabase db(file_name);
    EXPECT_EQ(file_name, db.file_path());
    ASSERT_TRUE(db.CommitChanges(false, storage));
  }
  EXPECT_TRUE(base::PathExists(file_name));

  {
    // Check that reading an existing db with data in it
    // keeps the DB on disk on close.
    DOMStorageDatabase db(file_name);
    DOMStorageValuesMap values;
    db.ReadAllValues(&values);
    EXPECT_EQ(storage.size(), values.size());
  }

  EXPECT_TRUE(base::PathExists(file_name));
  storage.clear();

  {
    DOMStorageDatabase db(file_name);
    ASSERT_TRUE(db.CommitChanges(true, storage));
  }
  EXPECT_FALSE(base::PathExists(file_name));

  // Now ensure that a series of updates and removals whose net effect
  // is an empty database also triggers deletion.
  CreateMapWithValues(&storage);
  {
    DOMStorageDatabase db(file_name);
    ASSERT_TRUE(db.CommitChanges(false, storage));
  }

  EXPECT_TRUE(base::PathExists(file_name));

  {
    DOMStorageDatabase db(file_name);
    ASSERT_TRUE(db.CommitChanges(false, storage));
    DOMStorageValuesMap::iterator it = storage.begin();
    for (; it != storage.end(); ++it)
      it->second = base::NullableString16();
    ASSERT_TRUE(db.CommitChanges(false, storage));
  }
  EXPECT_FALSE(base::PathExists(file_name));
}

TEST(DOMStorageDatabaseTest, TestLazyOpenIsLazy) {
  // This test needs to operate with a file on disk to ensure that we will
  // open a file that already exists when only invoking ReadAllValues.
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath file_name =
      temp_dir.path().AppendASCII("TestDOMStorageDatabase.db");

  DOMStorageDatabase db(file_name);
  EXPECT_FALSE(db.IsOpen());
  DOMStorageValuesMap values;
  db.ReadAllValues(&values);
  // Reading an empty db should not open the database.
  EXPECT_FALSE(db.IsOpen());

  values[ASCIIToUTF16("key")] =
      base::NullableString16(ASCIIToUTF16("value"), false);
  db.CommitChanges(false, values);
  // Writing content should open the database.
  EXPECT_TRUE(db.IsOpen());

  db.Close();
  ASSERT_FALSE(db.IsOpen());

  // Reading from an existing database should open the database.
  CheckValuesMatch(&db, values);
  EXPECT_TRUE(db.IsOpen());
}

TEST(DOMStorageDatabaseTest, TestDetectSchemaVersion) {
  DOMStorageDatabase db;
  db.db_.reset(new sql::Connection());
  ASSERT_TRUE(db.db_->OpenInMemory());

  CreateInvalidValueColumnTable(db.db_.get());
  EXPECT_EQ(DOMStorageDatabase::INVALID, db.DetectSchemaVersion());

  CreateInvalidKeyColumnTable(db.db_.get());
  EXPECT_EQ(DOMStorageDatabase::INVALID, db.DetectSchemaVersion());

  CreateV1Table(db.db_.get());
  EXPECT_EQ(DOMStorageDatabase::V1, db.DetectSchemaVersion());

  CreateV2Table(db.db_.get());
  EXPECT_EQ(DOMStorageDatabase::V2, db.DetectSchemaVersion());
}

TEST(DOMStorageDatabaseTest, TestLazyOpenUpgradesDatabase) {
  // This test needs to operate with a file on disk so that we
  // can create a table at version 1 and then close it again
  // so that LazyOpen sees there is work to do (LazyOpen will return
  // early if the database is already open).
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath file_name =
      temp_dir.path().AppendASCII("TestDOMStorageDatabase.db");

  DOMStorageDatabase db(file_name);
  db.db_.reset(new sql::Connection());
  ASSERT_TRUE(db.db_->Open(file_name));
  CreateV1Table(db.db_.get());
  db.Close();

  EXPECT_TRUE(db.LazyOpen(true));
  EXPECT_EQ(DOMStorageDatabase::V2, db.DetectSchemaVersion());
}

TEST(DOMStorageDatabaseTest, SimpleWriteAndReadBack) {
  DOMStorageDatabase db;

  DOMStorageValuesMap storage;
  CreateMapWithValues(&storage);

  EXPECT_TRUE(db.CommitChanges(false, storage));
  CheckValuesMatch(&db, storage);
}

TEST(DOMStorageDatabaseTest, WriteWithClear) {
  DOMStorageDatabase db;

  DOMStorageValuesMap storage;
  CreateMapWithValues(&storage);

  ASSERT_TRUE(db.CommitChanges(false, storage));
  CheckValuesMatch(&db, storage);

  // Insert some values, clearing the database first.
  storage.clear();
  storage[ASCIIToUTF16("another_key")] =
      base::NullableString16(ASCIIToUTF16("test"), false);
  ASSERT_TRUE(db.CommitChanges(true, storage));
  CheckValuesMatch(&db, storage);

  // Now clear the values without inserting any new ones.
  storage.clear();
  ASSERT_TRUE(db.CommitChanges(true, storage));
  CheckValuesMatch(&db, storage);
}

TEST(DOMStorageDatabaseTest, UpgradeFromV1ToV2WithData) {
  const base::string16 kCannedKey = ASCIIToUTF16("foo");
  const base::NullableString16 kCannedValue(ASCIIToUTF16("bar"), false);
  DOMStorageValuesMap expected;
  expected[kCannedKey] = kCannedValue;

  DOMStorageDatabase db;
  db.db_.reset(new sql::Connection());
  ASSERT_TRUE(db.db_->OpenInMemory());
  CreateV1Table(db.db_.get());
  InsertDataV1(db.db_.get(), kCannedKey, kCannedValue.string());

  ASSERT_TRUE(db.UpgradeVersion1To2());

  EXPECT_EQ(DOMStorageDatabase::V2, db.DetectSchemaVersion());

  CheckValuesMatch(&db, expected);
}

TEST(DOMStorageDatabaseTest, TestSimpleRemoveOneValue) {
  DOMStorageDatabase db;

  ASSERT_TRUE(db.LazyOpen(true));
  const base::string16 kCannedKey = ASCIIToUTF16("test");
  const base::NullableString16 kCannedValue(ASCIIToUTF16("data"), false);
  DOMStorageValuesMap expected;
  expected[kCannedKey] = kCannedValue;

  // First write some data into the database.
  ASSERT_TRUE(db.CommitChanges(false, expected));
  CheckValuesMatch(&db, expected);

  DOMStorageValuesMap values;
  // A null string in the map should mean that that key gets
  // removed.
  values[kCannedKey] = base::NullableString16();
  EXPECT_TRUE(db.CommitChanges(false, values));

  expected.clear();
  CheckValuesMatch(&db, expected);
}

TEST(DOMStorageDatabaseTest, TestCanOpenAndReadWebCoreDatabase) {
  base::FilePath webcore_database;
  PathService::Get(base::DIR_SOURCE_ROOT, &webcore_database);
  webcore_database = webcore_database.AppendASCII("webkit");
  webcore_database = webcore_database.AppendASCII("data");
  webcore_database = webcore_database.AppendASCII("dom_storage");
  webcore_database =
      webcore_database.AppendASCII("webcore_test_database.localstorage");

  ASSERT_TRUE(base::PathExists(webcore_database));

  DOMStorageDatabase db(webcore_database);
  DOMStorageValuesMap values;
  db.ReadAllValues(&values);
  EXPECT_TRUE(db.IsOpen());
  EXPECT_EQ(2u, values.size());

  DOMStorageValuesMap::const_iterator it =
      values.find(ASCIIToUTF16("value"));
  EXPECT_TRUE(it != values.end());
  EXPECT_EQ(ASCIIToUTF16("I am in local storage!"), it->second.string());

  it = values.find(ASCIIToUTF16("timestamp"));
  EXPECT_TRUE(it != values.end());
  EXPECT_EQ(ASCIIToUTF16("1326738338841"), it->second.string());

  it = values.find(ASCIIToUTF16("not_there"));
  EXPECT_TRUE(it == values.end());
}

TEST(DOMStorageDatabaseTest, TestCanOpenFileThatIsNotADatabase) {
  // Write into the temporary file first.
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath file_name =
      temp_dir.path().AppendASCII("TestDOMStorageDatabase.db");

  const char kData[] = "I am not a database.";
  file_util::WriteFile(file_name, kData, strlen(kData));

  {
    sql::ScopedErrorIgnorer ignore_errors;
    ignore_errors.IgnoreError(SQLITE_IOERR_SHORT_READ);

    // Try and open the file. As it's not a database, we should end up deleting
    // it and creating a new, valid file, so everything should actually
    // succeed.
    DOMStorageDatabase db(file_name);
    DOMStorageValuesMap values;
    CreateMapWithValues(&values);
    EXPECT_TRUE(db.CommitChanges(true, values));
    EXPECT_TRUE(db.CommitChanges(false, values));
    EXPECT_TRUE(db.IsOpen());

    CheckValuesMatch(&db, values);

    ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
  }

  {
    sql::ScopedErrorIgnorer ignore_errors;
    ignore_errors.IgnoreError(SQLITE_CANTOPEN);

    // Try to open a directory, we should fail gracefully and not attempt
    // to delete it.
    DOMStorageDatabase db(temp_dir.path());
    DOMStorageValuesMap values;
    CreateMapWithValues(&values);
    EXPECT_FALSE(db.CommitChanges(true, values));
    EXPECT_FALSE(db.CommitChanges(false, values));
    EXPECT_FALSE(db.IsOpen());

    values.clear();

    db.ReadAllValues(&values);
    EXPECT_EQ(0u, values.size());
    EXPECT_FALSE(db.IsOpen());

    EXPECT_TRUE(base::PathExists(temp_dir.path()));

    ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
  }
}

}  // namespace content
