// 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/indexed_db/indexed_db_database.h"

#include <set>

#include "base/auto_reset.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/indexed_db/indexed_db.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
#include "content/browser/indexed_db/indexed_db_cursor.h"
#include "content/browser/indexed_db/indexed_db_fake_backing_store.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/mock_indexed_db_callbacks.h"
#include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
#include "content/browser/indexed_db/mock_indexed_db_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::ASCIIToUTF16;

namespace {
const int kFakeChildProcessId = 0;
}

namespace content {

TEST(IndexedDBDatabaseTest, BackingStoreRetention) {
  scoped_refptr<IndexedDBFakeBackingStore> backing_store =
      new IndexedDBFakeBackingStore();
  EXPECT_TRUE(backing_store->HasOneRef());

  scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory();
  leveldb::Status s;
  scoped_refptr<IndexedDBDatabase> db =
      IndexedDBDatabase::Create(ASCIIToUTF16("db"),
                                backing_store,
                                factory,
                                IndexedDBDatabase::Identifier(),
                                &s);
  ASSERT_TRUE(s.ok());
  EXPECT_FALSE(backing_store->HasOneRef());  // local and db
  db = NULL;
  EXPECT_TRUE(backing_store->HasOneRef());  // local
}

TEST(IndexedDBDatabaseTest, ConnectionLifecycle) {
  scoped_refptr<IndexedDBFakeBackingStore> backing_store =
      new IndexedDBFakeBackingStore();
  EXPECT_TRUE(backing_store->HasOneRef());  // local

  scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory();
  leveldb::Status s;
  scoped_refptr<IndexedDBDatabase> db =
      IndexedDBDatabase::Create(ASCIIToUTF16("db"),
                                backing_store,
                                factory,
                                IndexedDBDatabase::Identifier(),
                                &s);
  ASSERT_TRUE(s.ok());
  EXPECT_FALSE(backing_store->HasOneRef());  // local and db

  scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks());
  scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
      new MockIndexedDBDatabaseCallbacks());
  const int64 transaction_id1 = 1;
  IndexedDBPendingConnection connection1(
      request1,
      callbacks1,
      kFakeChildProcessId,
      transaction_id1,
      IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
  db->OpenConnection(connection1);

  EXPECT_FALSE(backing_store->HasOneRef());  // db, connection count > 0

  scoped_refptr<MockIndexedDBCallbacks> request2(new MockIndexedDBCallbacks());
  scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2(
      new MockIndexedDBDatabaseCallbacks());
  const int64 transaction_id2 = 2;
  IndexedDBPendingConnection connection2(
      request2,
      callbacks2,
      kFakeChildProcessId,
      transaction_id2,
      IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
  db->OpenConnection(connection2);

  EXPECT_FALSE(backing_store->HasOneRef());  // local and connection

  request1->connection()->ForceClose();
  EXPECT_FALSE(request1->connection()->IsConnected());

  EXPECT_FALSE(backing_store->HasOneRef());  // local and connection

  request2->connection()->ForceClose();
  EXPECT_FALSE(request2->connection()->IsConnected());

  EXPECT_TRUE(backing_store->HasOneRef());
  EXPECT_FALSE(db->backing_store());

  db = NULL;
}

TEST(IndexedDBDatabaseTest, ForcedClose) {
  scoped_refptr<IndexedDBFakeBackingStore> backing_store =
      new IndexedDBFakeBackingStore();
  EXPECT_TRUE(backing_store->HasOneRef());

  scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory();
  leveldb::Status s;
  scoped_refptr<IndexedDBDatabase> database =
      IndexedDBDatabase::Create(ASCIIToUTF16("db"),
                                backing_store,
                                factory,
                                IndexedDBDatabase::Identifier(),
                                &s);
  ASSERT_TRUE(s.ok());
  EXPECT_FALSE(backing_store->HasOneRef());  // local and db

  scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks(
      new MockIndexedDBDatabaseCallbacks());
  scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks());
  const int64 upgrade_transaction_id = 3;
  IndexedDBPendingConnection connection(
      request,
      callbacks,
      kFakeChildProcessId,
      upgrade_transaction_id,
      IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
  database->OpenConnection(connection);
  EXPECT_EQ(database, request->connection()->database());

  const int64 transaction_id = 123;
  const std::vector<int64> scope;
  database->CreateTransaction(transaction_id,
                              request->connection(),
                              scope,
                              blink::WebIDBTransactionModeReadOnly);

  request->connection()->ForceClose();

  EXPECT_TRUE(backing_store->HasOneRef());  // local
  EXPECT_TRUE(callbacks->abort_called());
}

class MockDeleteCallbacks : public IndexedDBCallbacks {
 public:
  MockDeleteCallbacks()
      : IndexedDBCallbacks(NULL, 0, 0),
        blocked_called_(false),
        success_called_(false) {}

  virtual void OnBlocked(int64 existing_version) OVERRIDE {
    blocked_called_ = true;
  }
  virtual void OnSuccess(int64 result) OVERRIDE { success_called_ = true; }

  bool blocked_called() const { return blocked_called_; }
  bool success_called() const { return success_called_; }

 private:
  virtual ~MockDeleteCallbacks() {}

  bool blocked_called_;
  bool success_called_;

  DISALLOW_COPY_AND_ASSIGN(MockDeleteCallbacks);
};

TEST(IndexedDBDatabaseTest, PendingDelete) {
  scoped_refptr<IndexedDBFakeBackingStore> backing_store =
      new IndexedDBFakeBackingStore();
  EXPECT_TRUE(backing_store->HasOneRef());  // local

  scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory();
  leveldb::Status s;
  scoped_refptr<IndexedDBDatabase> db =
      IndexedDBDatabase::Create(ASCIIToUTF16("db"),
                                backing_store,
                                factory,
                                IndexedDBDatabase::Identifier(),
                                &s);
  ASSERT_TRUE(s.ok());
  EXPECT_FALSE(backing_store->HasOneRef());  // local and db

  scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks());
  scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
      new MockIndexedDBDatabaseCallbacks());
  const int64 transaction_id1 = 1;
  IndexedDBPendingConnection connection(
      request1,
      callbacks1,
      kFakeChildProcessId,
      transaction_id1,
      IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
  db->OpenConnection(connection);

  EXPECT_FALSE(backing_store->HasOneRef());  // local and db

  scoped_refptr<MockDeleteCallbacks> request2(new MockDeleteCallbacks());
  db->DeleteDatabase(request2);

  EXPECT_FALSE(request2->blocked_called());
  db->VersionChangeIgnored();
  EXPECT_TRUE(request2->blocked_called());

  EXPECT_FALSE(backing_store->HasOneRef());  // local and db

  db->Close(request1->connection(), true /* forced */);

  EXPECT_FALSE(db->backing_store());
  EXPECT_TRUE(backing_store->HasOneRef());  // local
  EXPECT_TRUE(request2->success_called());
}

void DummyOperation(IndexedDBTransaction* transaction) {
}

class IndexedDBDatabaseOperationTest : public testing::Test {
 public:
  IndexedDBDatabaseOperationTest()
      : commit_success_(leveldb::Status::OK()),
        factory_(new MockIndexedDBFactory()) {}

  virtual void SetUp() {
    backing_store_ = new IndexedDBFakeBackingStore();
    leveldb::Status s;
    db_ = IndexedDBDatabase::Create(ASCIIToUTF16("db"),
                                    backing_store_,
                                    factory_,
                                    IndexedDBDatabase::Identifier(),
                                    &s);
    ASSERT_TRUE(s.ok());

    request_ = new MockIndexedDBCallbacks();
    callbacks_ = new MockIndexedDBDatabaseCallbacks();
    const int64 transaction_id = 1;
    db_->OpenConnection(IndexedDBPendingConnection(
        request_,
        callbacks_,
        kFakeChildProcessId,
        transaction_id,
        IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION));
    EXPECT_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION,
              db_->metadata().int_version);

    transaction_ = new IndexedDBTransaction(
        transaction_id,
        callbacks_,
        std::set<int64>() /*scope*/,
        blink::WebIDBTransactionModeVersionChange,
        db_,
        new IndexedDBFakeBackingStore::FakeTransaction(commit_success_));
    db_->TransactionCreated(transaction_);

    // Add a dummy task which takes the place of the VersionChangeOperation
    // which kicks off the upgrade. This ensures that the transaction has
    // processed at least one task before the CreateObjectStore call.
    transaction_->ScheduleTask(base::Bind(&DummyOperation));
  }

  void RunPostedTasks() { base::RunLoop().RunUntilIdle(); }

 protected:
  scoped_refptr<IndexedDBFakeBackingStore> backing_store_;
  scoped_refptr<IndexedDBDatabase> db_;
  scoped_refptr<MockIndexedDBCallbacks> request_;
  scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks_;
  scoped_refptr<IndexedDBTransaction> transaction_;

  leveldb::Status commit_success_;

 private:
  base::MessageLoop message_loop_;
  scoped_refptr<MockIndexedDBFactory> factory_;

  DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabaseOperationTest);
};

TEST_F(IndexedDBDatabaseOperationTest, CreateObjectStore) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64 store_id = 1001;
  db_->CreateObjectStore(transaction_->id(),
                         store_id,
                         ASCIIToUTF16("store"),
                         IndexedDBKeyPath(),
                         false /*auto_increment*/);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  RunPostedTasks();
  transaction_->Commit();
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
}

TEST_F(IndexedDBDatabaseOperationTest, CreateIndex) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64 store_id = 1001;
  db_->CreateObjectStore(transaction_->id(),
                         store_id,
                         ASCIIToUTF16("store"),
                         IndexedDBKeyPath(),
                         false /*auto_increment*/);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  const int64 index_id = 2002;
  db_->CreateIndex(transaction_->id(),
                   store_id,
                   index_id,
                   ASCIIToUTF16("index"),
                   IndexedDBKeyPath(),
                   false /*unique*/,
                   false /*multi_entry*/);
  EXPECT_EQ(
      1ULL,
      db_->metadata().object_stores.find(store_id)->second.indexes.size());
  RunPostedTasks();
  transaction_->Commit();
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  EXPECT_EQ(
      1ULL,
      db_->metadata().object_stores.find(store_id)->second.indexes.size());
}

class IndexedDBDatabaseOperationAbortTest
    : public IndexedDBDatabaseOperationTest {
 public:
  IndexedDBDatabaseOperationAbortTest() {
    commit_success_ = leveldb::Status::NotFound("Bummer.");
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabaseOperationAbortTest);
};

TEST_F(IndexedDBDatabaseOperationAbortTest, CreateObjectStore) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64 store_id = 1001;
  db_->CreateObjectStore(transaction_->id(),
                         store_id,
                         ASCIIToUTF16("store"),
                         IndexedDBKeyPath(),
                         false /*auto_increment*/);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  RunPostedTasks();
  transaction_->Commit();
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
}

TEST_F(IndexedDBDatabaseOperationAbortTest, CreateIndex) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64 store_id = 1001;
  db_->CreateObjectStore(transaction_->id(),
                         store_id,
                         ASCIIToUTF16("store"),
                         IndexedDBKeyPath(),
                         false /*auto_increment*/);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  const int64 index_id = 2002;
  db_->CreateIndex(transaction_->id(),
                   store_id,
                   index_id,
                   ASCIIToUTF16("index"),
                   IndexedDBKeyPath(),
                   false /*unique*/,
                   false /*multi_entry*/);
  EXPECT_EQ(
      1ULL,
      db_->metadata().object_stores.find(store_id)->second.indexes.size());
  RunPostedTasks();
  transaction_->Commit();
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
}

TEST_F(IndexedDBDatabaseOperationTest, CreatePutDelete) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64 store_id = 1001;

  // Creation is synchronous.
  db_->CreateObjectStore(transaction_->id(),
                         store_id,
                         ASCIIToUTF16("store"),
                         IndexedDBKeyPath(),
                         false /*auto_increment*/);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());


  // Put is asynchronous
  IndexedDBValue value("value1", std::vector<IndexedDBBlobInfo>());
  ScopedVector<webkit_blob::BlobDataHandle> handles;
  scoped_ptr<IndexedDBKey> key(new IndexedDBKey("key"));
  std::vector<IndexedDBDatabase::IndexKeys> index_keys;
  scoped_refptr<MockIndexedDBCallbacks> request(
      new MockIndexedDBCallbacks(false));
  db_->Put(transaction_->id(),
           store_id,
           &value,
           &handles,
           key.Pass(),
           blink::WebIDBPutModeAddOnly,
           request,
           index_keys);

  // Deletion is asynchronous.
  db_->DeleteObjectStore(transaction_->id(),
                         store_id);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());

  // This will execute the Put then Delete.
  RunPostedTasks();
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());

  transaction_->Commit();  // Cleans up the object hierarchy.
}

}  // namespace content
