// 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 "chrome/browser/sync_file_system/drive_backend/metadata_database.h"

#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/google_apis/drive_api_parser.h"
#include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"

#define FPL(a) FILE_PATH_LITERAL(a)

namespace sync_file_system {
namespace drive_backend {

namespace {

typedef MetadataDatabase::FileIDList FileIDList;

const int64 kInitialChangeID = 1234;
const int64 kSyncRootTrackerID = 100;
const char kSyncRootFolderID[] = "sync_root_folder_id";

// This struct is used to setup initial state of the database in the test and
// also used to match to the modified content of the database as the
// expectation.
struct TrackedFile {
  // Holds the latest remote metadata which may be not-yet-synced to |tracker|.
  FileMetadata metadata;
  FileTracker tracker;

  // Implies the file should not in the database.
  bool should_be_absent;

  // Implies the file should have a tracker in the database but should have no
  // metadata.
  bool tracker_only;

  TrackedFile() : should_be_absent(false), tracker_only(false) {}
};

void ExpectEquivalent(const ServiceMetadata* left,
                      const ServiceMetadata* right) {
  test_util::ExpectEquivalentServiceMetadata(*left, *right);
}

void ExpectEquivalent(const FileDetails* left, const FileDetails* right) {
  if (!left) {
    ASSERT_FALSE(right);
    return;
  }
  ASSERT_TRUE(right);
  test_util::ExpectEquivalentDetails(*left, *right);
}

void ExpectEquivalent(const FileMetadata* left, const FileMetadata* right) {
  if (!left) {
    ASSERT_FALSE(right);
    return;
  }
  ASSERT_TRUE(right);
  test_util::ExpectEquivalentMetadata(*left, *right);
}

void ExpectEquivalent(const FileTracker* left, const FileTracker* right) {
  if (!left) {
    ASSERT_FALSE(right);
    return;
  }
  ASSERT_TRUE(right);
  test_util::ExpectEquivalentTrackers(*left, *right);
}

template <typename Container>
void ExpectEquivalentMaps(const Container& left, const Container& right);
template <typename Key, typename Value, typename Compare>
void ExpectEquivalent(const std::map<Key, Value, Compare>& left,
                      const std::map<Key, Value, Compare>& right) {
  ExpectEquivalentMaps(left, right);
}

template <typename Container>
void ExpectEquivalentSets(const Container& left, const Container& right);
template <typename Value, typename Compare>
void ExpectEquivalent(const std::set<Value, Compare>& left,
                      const std::set<Value, Compare>& right) {
  return ExpectEquivalentSets(left, right);
}

void ExpectEquivalent(const TrackerSet& left,
                      const TrackerSet& right) {
  {
    SCOPED_TRACE("Expect equivalent active_tracker");
    ExpectEquivalent(left.active_tracker(), right.active_tracker());
  }
  ExpectEquivalent(left.tracker_set(), right.tracker_set());
}

template <typename Container>
void ExpectEquivalentMaps(const Container& left, const Container& right) {
  ASSERT_EQ(left.size(), right.size());

  typedef typename Container::const_iterator const_iterator;
  const_iterator left_itr = left.begin();
  const_iterator right_itr = right.begin();
  while (left_itr != left.end()) {
    EXPECT_EQ(left_itr->first, right_itr->first);
    ExpectEquivalent(left_itr->second, right_itr->second);
    ++left_itr;
    ++right_itr;
  }
}

template <typename Container>
void ExpectEquivalentSets(const Container& left, const Container& right) {
  ASSERT_EQ(left.size(), right.size());

  typedef typename Container::const_iterator const_iterator;
  const_iterator left_itr = left.begin();
  const_iterator right_itr = right.begin();
  while (left_itr != left.end()) {
    ExpectEquivalent(*left_itr, *right_itr);
    ++left_itr;
    ++right_itr;
  }
}

}  // namespace

class MetadataDatabaseTest : public testing::Test {
 public:
  MetadataDatabaseTest()
      : next_change_id_(kInitialChangeID + 1),
        next_tracker_id_(kSyncRootTrackerID + 1),
        next_file_id_number_(1),
        next_md5_sequence_number_(1) {}

  virtual ~MetadataDatabaseTest() {}

  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
  }

  virtual void TearDown() OVERRIDE { DropDatabase(); }

 protected:
  std::string GenerateFileID() {
    return "file_id_" + base::Int64ToString(next_file_id_number_++);
  }

  int64 GetTrackerIDByFileID(const std::string& file_id) {
    TrackerSet trackers;
    if (metadata_database_->FindTrackersByFileID(file_id, &trackers)) {
      EXPECT_FALSE(trackers.empty());
      return (*trackers.begin())->tracker_id();
    }
    return 0;
  }

  SyncStatusCode InitializeMetadataDatabase() {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    MetadataDatabase::Create(base::MessageLoopProxy::current(),
                             database_dir_.path(),
                             CreateResultReceiver(&status,
                                                  &metadata_database_));
    message_loop_.RunUntilIdle();
    return status;
  }

  void DropDatabase() {
    metadata_database_.reset();
    message_loop_.RunUntilIdle();
  }

  void SetUpDatabaseByTrackedFiles(const TrackedFile** tracked_files,
                                   int size) {
    scoped_ptr<leveldb::DB> db = InitializeLevelDB();
    ASSERT_TRUE(db);

    for (int i = 0; i < size; ++i) {
      const TrackedFile* file = tracked_files[i];
      if (file->should_be_absent)
        continue;
      if (!file->tracker_only)
        EXPECT_TRUE(PutFileToDB(db.get(), file->metadata).ok());
      EXPECT_TRUE(PutTrackerToDB(db.get(), file->tracker).ok());
    }
  }

  void VerifyTrackedFile(const TrackedFile& file) {
    if (!file.should_be_absent) {
      if (file.tracker_only) {
        EXPECT_FALSE(metadata_database()->FindFileByFileID(
            file.metadata.file_id(), NULL));
      } else {
        VerifyFile(file.metadata);
      }
      VerifyTracker(file.tracker);
      return;
    }

    EXPECT_FALSE(metadata_database()->FindFileByFileID(
        file.metadata.file_id(), NULL));
    EXPECT_FALSE(metadata_database()->FindTrackerByTrackerID(
        file.tracker.tracker_id(), NULL));
  }

  void VerifyTrackedFiles(const TrackedFile** tracked_files, int size) {
    for (int i = 0; i < size; ++i)
      VerifyTrackedFile(*tracked_files[i]);
  }

  MetadataDatabase* metadata_database() { return metadata_database_.get(); }

  leveldb::DB* db() {
    if (!metadata_database_)
      return NULL;
    return metadata_database_->db_.get();
  }

  scoped_ptr<leveldb::DB> InitializeLevelDB() {
    leveldb::DB* db = NULL;
    leveldb::Options options;
    options.create_if_missing = true;
    options.max_open_files = 0;  // Use minimum.
    leveldb::Status status =
        leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db);
    EXPECT_TRUE(status.ok());

    db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3));
    SetUpServiceMetadata(db);

    return make_scoped_ptr(db);
  }

  void SetUpServiceMetadata(leveldb::DB* db) {
    ServiceMetadata service_metadata;
    service_metadata.set_largest_change_id(kInitialChangeID);
    service_metadata.set_sync_root_tracker_id(kSyncRootTrackerID);
    service_metadata.set_next_tracker_id(next_tracker_id_);
    std::string value;
    ASSERT_TRUE(service_metadata.SerializeToString(&value));
    db->Put(leveldb::WriteOptions(), "SERVICE", value);
  }

  FileMetadata CreateSyncRootMetadata() {
    FileMetadata sync_root;
    sync_root.set_file_id(kSyncRootFolderID);
    FileDetails* details = sync_root.mutable_details();
    details->set_title("Chrome Syncable FileSystem");
    details->set_file_kind(FILE_KIND_FOLDER);
    return sync_root;
  }

  FileMetadata CreateFileMetadata(const FileMetadata& parent,
                                  const std::string& title) {
    FileMetadata file;
    file.set_file_id(GenerateFileID());
    FileDetails* details = file.mutable_details();
    details->add_parent_folder_ids(parent.file_id());
    details->set_title(title);
    details->set_file_kind(FILE_KIND_FILE);
    details->set_md5(
        "md5_value_" + base::Int64ToString(next_md5_sequence_number_++));
    return file;
  }

  FileMetadata CreateFolderMetadata(const FileMetadata& parent,
                                    const std::string& title) {
    FileMetadata folder;
    folder.set_file_id(GenerateFileID());
    FileDetails* details = folder.mutable_details();
    details->add_parent_folder_ids(parent.file_id());
    details->set_title(title);
    details->set_file_kind(FILE_KIND_FOLDER);
    return folder;
  }

  FileTracker CreateSyncRootTracker(const FileMetadata& sync_root) {
    FileTracker sync_root_tracker;
    sync_root_tracker.set_tracker_id(kSyncRootTrackerID);
    sync_root_tracker.set_parent_tracker_id(0);
    sync_root_tracker.set_file_id(sync_root.file_id());
    sync_root_tracker.set_dirty(false);
    sync_root_tracker.set_active(true);
    sync_root_tracker.set_needs_folder_listing(false);
    *sync_root_tracker.mutable_synced_details() = sync_root.details();
    return sync_root_tracker;
  }

  FileTracker CreateTracker(const FileTracker& parent_tracker,
                            const FileMetadata& file) {
    FileTracker tracker;
    tracker.set_tracker_id(next_tracker_id_++);
    tracker.set_parent_tracker_id(parent_tracker.tracker_id());
    tracker.set_file_id(file.file_id());
    tracker.set_app_id(parent_tracker.app_id());
    tracker.set_tracker_kind(TRACKER_KIND_REGULAR);
    tracker.set_dirty(false);
    tracker.set_active(true);
    tracker.set_needs_folder_listing(false);
    *tracker.mutable_synced_details() = file.details();
    return tracker;
  }

  TrackedFile CreateTrackedSyncRoot() {
    TrackedFile sync_root;
    sync_root.metadata = CreateSyncRootMetadata();
    sync_root.tracker = CreateSyncRootTracker(sync_root.metadata);
    return sync_root;
  }

  TrackedFile CreateTrackedAppRoot(const TrackedFile& sync_root,
                                   const std::string& app_id) {
    TrackedFile app_root(CreateTrackedFolder(sync_root, app_id));
    app_root.tracker.set_app_id(app_id);
    app_root.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT);
    return app_root;
  }

  TrackedFile CreateTrackedFile(const TrackedFile& parent,
                                const std::string& title) {
    TrackedFile file;
    file.metadata = CreateFileMetadata(parent.metadata, title);
    file.tracker = CreateTracker(parent.tracker, file.metadata);
    return file;
  }

  TrackedFile CreateTrackedFolder(const TrackedFile& parent,
                                  const std::string& title) {
    TrackedFile folder;
    folder.metadata = CreateFolderMetadata(parent.metadata, title);
    folder.tracker = CreateTracker(parent.tracker, folder.metadata);
    return folder;
  }

  scoped_ptr<google_apis::FileResource> CreateFileResourceFromMetadata(
      const FileMetadata& file) {
    scoped_ptr<google_apis::FileResource> file_resource(
        new google_apis::FileResource);
    ScopedVector<google_apis::ParentReference> parents;
    for (int i = 0; i < file.details().parent_folder_ids_size(); ++i) {
      scoped_ptr<google_apis::ParentReference> parent(
          new google_apis::ParentReference);
      parent->set_file_id(file.details().parent_folder_ids(i));
      parents.push_back(parent.release());
    }

    file_resource->set_file_id(file.file_id());
    file_resource->set_parents(parents.Pass());
    file_resource->set_title(file.details().title());
    if (file.details().file_kind() == FILE_KIND_FOLDER)
      file_resource->set_mime_type("application/vnd.google-apps.folder");
    else if (file.details().file_kind() == FILE_KIND_FILE)
      file_resource->set_mime_type("text/plain");
    else
      file_resource->set_mime_type("application/vnd.google-apps.document");
    file_resource->set_md5_checksum(file.details().md5());
    file_resource->set_etag(file.details().etag());
    file_resource->set_created_date(base::Time::FromInternalValue(
        file.details().creation_time()));
    file_resource->set_modified_date(base::Time::FromInternalValue(
        file.details().modification_time()));

    return file_resource.Pass();
  }

  scoped_ptr<google_apis::ChangeResource> CreateChangeResourceFromMetadata(
      const FileMetadata& file) {
    scoped_ptr<google_apis::ChangeResource> change(
        new google_apis::ChangeResource);
    change->set_change_id(file.details().change_id());
    change->set_file_id(file.file_id());
    change->set_deleted(file.details().deleted());
    if (change->is_deleted())
      return change.Pass();

    change->set_file(CreateFileResourceFromMetadata(file));
    return change.Pass();
  }

  void ApplyRenameChangeToMetadata(const std::string& new_title,
                                   FileMetadata* file) {
    FileDetails* details = file->mutable_details();
    details->set_title(new_title);
    details->set_change_id(next_change_id_++);
  }

  void ApplyReorganizeChangeToMetadata(const std::string& new_parent,
                                       FileMetadata* file) {
    FileDetails* details = file->mutable_details();
    details->clear_parent_folder_ids();
    details->add_parent_folder_ids(new_parent);
    details->set_change_id(next_change_id_++);
  }

  void ApplyContentChangeToMetadata(FileMetadata* file) {
    FileDetails* details = file->mutable_details();
    details->set_md5(
        "md5_value_" + base::Int64ToString(next_md5_sequence_number_++));
    details->set_change_id(next_change_id_++);
  }

  void PushToChangeList(scoped_ptr<google_apis::ChangeResource> change,
                        ScopedVector<google_apis::ChangeResource>* changes) {
    changes->push_back(change.release());
  }

  leveldb::Status PutFileToDB(leveldb::DB* db, const FileMetadata& file) {
    std::string key = "FILE: " + file.file_id();
    std::string value;
    file.SerializeToString(&value);
    return db->Put(leveldb::WriteOptions(), key, value);
  }

  leveldb::Status PutTrackerToDB(leveldb::DB* db,
                                 const FileTracker& tracker) {
    std::string key = "TRACKER: " + base::Int64ToString(tracker.tracker_id());
    std::string value;
    tracker.SerializeToString(&value);
    return db->Put(leveldb::WriteOptions(), key, value);
  }

  void VerifyReloadConsistency() {
    scoped_ptr<MetadataDatabase> metadata_database_2;
    ASSERT_EQ(SYNC_STATUS_OK,
              MetadataDatabase::CreateForTesting(
                  metadata_database_->db_.Pass(),
                  &metadata_database_2));
    metadata_database_->db_ = metadata_database_2->db_.Pass();

    {
      SCOPED_TRACE("Expect equivalent service_metadata");
      ExpectEquivalent(metadata_database_->service_metadata_.get(),
                       metadata_database_2->service_metadata_.get());
    }

    {
      SCOPED_TRACE("Expect equivalent file_by_id_ contents.");
      ExpectEquivalent(metadata_database_->file_by_id_,
                       metadata_database_2->file_by_id_);
    }

    {
      SCOPED_TRACE("Expect equivalent tracker_by_id_ contents.");
      ExpectEquivalent(metadata_database_->tracker_by_id_,
                       metadata_database_2->tracker_by_id_);
    }

    {
      SCOPED_TRACE("Expect equivalent trackers_by_file_id_ contents.");
      ExpectEquivalent(metadata_database_->trackers_by_file_id_,
                       metadata_database_2->trackers_by_file_id_);
    }

    {
      SCOPED_TRACE("Expect equivalent app_root_by_app_id_ contents.");
      ExpectEquivalent(metadata_database_->app_root_by_app_id_,
                       metadata_database_2->app_root_by_app_id_);
    }

    {
      SCOPED_TRACE("Expect equivalent trackers_by_parent_and_title_ contents.");
      ExpectEquivalent(metadata_database_->trackers_by_parent_and_title_,
                       metadata_database_2->trackers_by_parent_and_title_);
    }

    {
      SCOPED_TRACE("Expect equivalent dirty_trackers_ contents.");
      ExpectEquivalent(metadata_database_->dirty_trackers_,
                       metadata_database_2->dirty_trackers_);
    }
  }

  void VerifyFile(const FileMetadata& file) {
    FileMetadata file_in_metadata_database;
    ASSERT_TRUE(metadata_database()->FindFileByFileID(
        file.file_id(), &file_in_metadata_database));

    SCOPED_TRACE("Expect equivalent " + file.file_id());
    ExpectEquivalent(&file, &file_in_metadata_database);
  }

  void VerifyTracker(const FileTracker& tracker) {
    FileTracker tracker_in_metadata_database;
    ASSERT_TRUE(metadata_database()->FindTrackerByTrackerID(
        tracker.tracker_id(), &tracker_in_metadata_database));

    SCOPED_TRACE("Expect equivalent tracker[" +
                 base::Int64ToString(tracker.tracker_id()) + "]");
    ExpectEquivalent(&tracker, &tracker_in_metadata_database);
  }

  SyncStatusCode RegisterApp(const std::string& app_id,
                             const std::string& folder_id) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->RegisterApp(
        app_id, folder_id,
        CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  SyncStatusCode DisableApp(const std::string& app_id) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->DisableApp(
        app_id, CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  SyncStatusCode EnableApp(const std::string& app_id) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->EnableApp(
        app_id, CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  SyncStatusCode UnregisterApp(const std::string& app_id) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->UnregisterApp(
        app_id, CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  SyncStatusCode UpdateByChangeList(
      ScopedVector<google_apis::ChangeResource> changes) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->UpdateByChangeList(
        changes.Pass(), CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  SyncStatusCode PopulateFolder(const std::string& folder_id,
                                const FileIDList& listed_children) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->PopulateFolderByChildList(
        folder_id, listed_children,
        CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  SyncStatusCode UpdateTracker(const FileTracker& tracker) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->UpdateTracker(
        tracker.tracker_id(), tracker.synced_details(),
        CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  SyncStatusCode PopulateInitialData(
      int64 largest_change_id,
      const google_apis::FileResource& sync_root_folder,
      const ScopedVector<google_apis::FileResource>& app_root_folders) {
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    metadata_database_->PopulateInitialData(
        largest_change_id,
        sync_root_folder,
        app_root_folders,
        CreateResultReceiver(&status));
    message_loop_.RunUntilIdle();
    return status;
  }

  void ResetTrackerID(FileTracker* tracker) {
    tracker->set_tracker_id(GetTrackerIDByFileID(tracker->file_id()));
  }

 private:
  base::ScopedTempDir database_dir_;
  base::MessageLoop message_loop_;

  scoped_ptr<MetadataDatabase> metadata_database_;

  int64 next_change_id_;
  int64 next_tracker_id_;
  int64 next_file_id_number_;
  int64 next_md5_sequence_number_;

  DISALLOW_COPY_AND_ASSIGN(MetadataDatabaseTest);
};

TEST_F(MetadataDatabaseTest, InitializationTest_Empty) {
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
  DropDatabase();
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
}

TEST_F(MetadataDatabaseTest, InitializationTest_SimpleTree) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile app_root(CreateTrackedFolder(sync_root, "app_id"));
  app_root.tracker.set_app_id(app_root.metadata.details().title());
  app_root.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT);

  TrackedFile file(CreateTrackedFile(app_root, "file"));
  TrackedFile folder(CreateTrackedFolder(app_root, "folder"));
  TrackedFile file_in_folder(CreateTrackedFile(folder, "file_in_folder"));
  TrackedFile orphaned_file(CreateTrackedFile(sync_root, "orphaned_file"));
  orphaned_file.metadata.mutable_details()->clear_parent_folder_ids();
  orphaned_file.tracker.set_parent_tracker_id(0);

  const TrackedFile* tracked_files[] = {
    &sync_root, &app_root, &file, &folder, &file_in_folder, &orphaned_file
  };

  SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files));
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());

  orphaned_file.should_be_absent = true;
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
}

TEST_F(MetadataDatabaseTest, AppManagementTest) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile app_root(CreateTrackedFolder(sync_root, "app_id"));
  app_root.tracker.set_app_id(app_root.metadata.details().title());
  app_root.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT);

  TrackedFile file(CreateTrackedFile(app_root, "file"));
  TrackedFile folder(CreateTrackedFolder(sync_root, "folder"));
  folder.tracker.set_active(false);

  const TrackedFile* tracked_files[] = {
    &sync_root, &app_root, &file, &folder,
  };
  SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files));
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));

  folder.tracker.set_app_id("foo");
  EXPECT_EQ(SYNC_STATUS_OK, RegisterApp(
      folder.tracker.app_id(), folder.metadata.file_id()));
  folder.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT);
  folder.tracker.set_active(true);
  folder.tracker.set_dirty(true);
  folder.tracker.set_needs_folder_listing(true);
  VerifyTrackedFile(folder);
  VerifyReloadConsistency();

  EXPECT_EQ(SYNC_STATUS_OK, DisableApp(folder.tracker.app_id()));
  folder.tracker.set_tracker_kind(TRACKER_KIND_DISABLED_APP_ROOT);
  VerifyTrackedFile(folder);
  VerifyReloadConsistency();

  EXPECT_EQ(SYNC_STATUS_OK, EnableApp(folder.tracker.app_id()));
  folder.tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT);
  VerifyTrackedFile(folder);
  VerifyReloadConsistency();

  EXPECT_EQ(SYNC_STATUS_OK, UnregisterApp(folder.tracker.app_id()));
  folder.tracker.set_app_id(std::string());
  folder.tracker.set_tracker_kind(TRACKER_KIND_REGULAR);
  folder.tracker.set_active(false);
  VerifyTrackedFile(folder);
  VerifyReloadConsistency();

  EXPECT_EQ(SYNC_STATUS_OK, UnregisterApp(app_root.tracker.app_id()));
  app_root.tracker.set_app_id(std::string());
  app_root.tracker.set_tracker_kind(TRACKER_KIND_REGULAR);
  app_root.tracker.set_active(false);
  app_root.tracker.set_dirty(true);
  file.should_be_absent = true;
  VerifyTrackedFile(app_root);
  VerifyTrackedFile(file);
  VerifyReloadConsistency();
}

TEST_F(MetadataDatabaseTest, BuildPathTest) {
  FileMetadata sync_root(CreateSyncRootMetadata());
  FileTracker sync_root_tracker(CreateSyncRootTracker(sync_root));

  FileMetadata app_root(CreateFolderMetadata(sync_root, "app_id"));
  FileTracker app_root_tracker(
      CreateTracker(sync_root_tracker, app_root));
  app_root_tracker.set_app_id(app_root.details().title());
  app_root_tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT);

  FileMetadata folder(CreateFolderMetadata(app_root, "folder"));
  FileTracker folder_tracker(CreateTracker(app_root_tracker, folder));

  FileMetadata file(CreateFolderMetadata(folder, "file"));
  FileTracker file_tracker(CreateTracker(folder_tracker, file));

  FileMetadata inactive_folder(CreateFolderMetadata(app_root, "folder"));
  FileTracker inactive_folder_tracker(CreateTracker(app_root_tracker,
                                                          inactive_folder));
  inactive_folder_tracker.set_active(false);

  {
    scoped_ptr<leveldb::DB> db = InitializeLevelDB();
    ASSERT_TRUE(db);

    EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
    EXPECT_TRUE(PutTrackerToDB(db.get(), sync_root_tracker).ok());
    EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
    EXPECT_TRUE(PutTrackerToDB(db.get(), app_root_tracker).ok());
    EXPECT_TRUE(PutFileToDB(db.get(), folder).ok());
    EXPECT_TRUE(PutTrackerToDB(db.get(), folder_tracker).ok());
    EXPECT_TRUE(PutFileToDB(db.get(), file).ok());
    EXPECT_TRUE(PutTrackerToDB(db.get(), file_tracker).ok());
  }

  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());

  base::FilePath path;
  EXPECT_FALSE(metadata_database()->BuildPathForTracker(
      sync_root_tracker.tracker_id(), &path));
  EXPECT_TRUE(metadata_database()->BuildPathForTracker(
      app_root_tracker.tracker_id(), &path));
  EXPECT_EQ(base::FilePath(FPL("/")).NormalizePathSeparators(), path);
  EXPECT_TRUE(metadata_database()->BuildPathForTracker(
      file_tracker.tracker_id(), &path));
  EXPECT_EQ(base::FilePath(FPL("/folder/file")).NormalizePathSeparators(),
            path);
}

TEST_F(MetadataDatabaseTest, UpdateByChangeListTest) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile app_root(CreateTrackedFolder(sync_root, "app_id"));
  TrackedFile disabled_app_root(CreateTrackedFolder(sync_root, "disabled_app"));
  TrackedFile file(CreateTrackedFile(app_root, "file"));
  TrackedFile renamed_file(CreateTrackedFile(app_root, "to be renamed"));
  TrackedFile folder(CreateTrackedFolder(app_root, "folder"));
  TrackedFile reorganized_file(
      CreateTrackedFile(app_root, "to be reorganized"));
  TrackedFile updated_file(
      CreateTrackedFile(app_root, "to be updated"));
  TrackedFile noop_file(CreateTrackedFile(app_root, "has noop change"));
  TrackedFile new_file(CreateTrackedFile(app_root, "to be added later"));
  new_file.should_be_absent = true;

  const TrackedFile* tracked_files[] = {
    &sync_root, &app_root, &disabled_app_root,
    &file, &renamed_file, &folder, &reorganized_file, &updated_file, &noop_file,
    &new_file,
  };

  SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files));
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());

  ApplyRenameChangeToMetadata("renamed", &renamed_file.metadata);
  ApplyReorganizeChangeToMetadata(folder.metadata.file_id(),
                                  &reorganized_file.metadata);
  ApplyContentChangeToMetadata(&updated_file.metadata);

  ScopedVector<google_apis::ChangeResource> changes;
  PushToChangeList(
      CreateChangeResourceFromMetadata(renamed_file.metadata), &changes);
  PushToChangeList(
      CreateChangeResourceFromMetadata(reorganized_file.metadata), &changes);
  PushToChangeList(
      CreateChangeResourceFromMetadata(updated_file.metadata), &changes);
  PushToChangeList(
      CreateChangeResourceFromMetadata(noop_file.metadata), &changes);
  PushToChangeList(
      CreateChangeResourceFromMetadata(new_file.metadata), &changes);
  EXPECT_EQ(SYNC_STATUS_OK, UpdateByChangeList(changes.Pass()));

  renamed_file.tracker.set_dirty(true);
  reorganized_file.tracker.set_dirty(true);
  updated_file.tracker.set_dirty(true);
  noop_file.tracker.set_dirty(true);
  new_file.tracker.clear_synced_details();
  new_file.tracker.set_active(false);
  new_file.tracker.set_dirty(true);
  ResetTrackerID(&new_file.tracker);
  EXPECT_NE(0, new_file.tracker.tracker_id());

  new_file.should_be_absent = false;

  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();
}

TEST_F(MetadataDatabaseTest, PopulateFolderTest_RegularFolder) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile app_root(CreateTrackedAppRoot(sync_root, "app_id"));
  app_root.tracker.set_app_id(app_root.metadata.details().title());

  TrackedFile folder_to_populate(
      CreateTrackedFolder(app_root, "folder_to_populate"));
  folder_to_populate.tracker.set_needs_folder_listing(true);
  folder_to_populate.tracker.set_dirty(true);

  TrackedFile known_file(CreateTrackedFile(folder_to_populate, "known_file"));
  TrackedFile new_file(CreateTrackedFile(folder_to_populate, "new_file"));
  new_file.should_be_absent = true;

  const TrackedFile* tracked_files[] = {
    &sync_root, &app_root, &folder_to_populate, &known_file, &new_file
  };

  SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files));
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));

  FileIDList listed_children;
  listed_children.push_back(known_file.metadata.file_id());
  listed_children.push_back(new_file.metadata.file_id());

  EXPECT_EQ(SYNC_STATUS_OK,
            PopulateFolder(folder_to_populate.metadata.file_id(),
                           listed_children));

  folder_to_populate.tracker.set_dirty(false);
  folder_to_populate.tracker.set_needs_folder_listing(false);
  ResetTrackerID(&new_file.tracker);
  new_file.tracker.set_dirty(true);
  new_file.tracker.set_active(false);
  new_file.tracker.clear_synced_details();
  new_file.should_be_absent = false;
  new_file.tracker_only = true;
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();
}

TEST_F(MetadataDatabaseTest, PopulateFolderTest_InactiveFolder) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile app_root(CreateTrackedAppRoot(sync_root, "app_id"));

  TrackedFile inactive_folder(CreateTrackedFolder(app_root, "inactive_folder"));
  inactive_folder.tracker.set_active(false);
  inactive_folder.tracker.set_dirty(true);

  TrackedFile new_file(
      CreateTrackedFile(inactive_folder, "file_in_inactive_folder"));
  new_file.should_be_absent = true;

  const TrackedFile* tracked_files[] = {
    &sync_root, &app_root, &inactive_folder, &new_file,
  };

  SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files));
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));

  FileIDList listed_children;
  listed_children.push_back(new_file.metadata.file_id());

  EXPECT_EQ(SYNC_STATUS_OK,
            PopulateFolder(inactive_folder.metadata.file_id(),
                           listed_children));
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();
}

TEST_F(MetadataDatabaseTest, PopulateFolderTest_DisabledAppRoot) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile disabled_app_root(
      CreateTrackedAppRoot(sync_root, "disabled_app"));
  disabled_app_root.tracker.set_dirty(true);
  disabled_app_root.tracker.set_needs_folder_listing(true);

  TrackedFile known_file(CreateTrackedFile(disabled_app_root, "known_file"));
  TrackedFile file(CreateTrackedFile(disabled_app_root, "file"));
  file.should_be_absent = true;

  const TrackedFile* tracked_files[] = {
    &sync_root, &disabled_app_root, &disabled_app_root, &known_file, &file,
  };

  SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files));
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));

  FileIDList disabled_app_children;
  disabled_app_children.push_back(file.metadata.file_id());
  EXPECT_EQ(SYNC_STATUS_OK, PopulateFolder(
      disabled_app_root.metadata.file_id(), disabled_app_children));
  ResetTrackerID(&file.tracker);
  file.tracker.clear_synced_details();
  file.tracker.set_dirty(true);
  file.tracker.set_active(false);
  file.should_be_absent = false;
  file.tracker_only = true;

  disabled_app_root.tracker.set_dirty(false);
  disabled_app_root.tracker.set_needs_folder_listing(false);
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();
}

TEST_F(MetadataDatabaseTest, UpdateTrackerTest) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile app_root(CreateTrackedAppRoot(sync_root, "app_root"));
  TrackedFile file(CreateTrackedFile(app_root, "file"));
  file.tracker.set_dirty(true);
  file.metadata.mutable_details()->set_title("renamed file");;

  TrackedFile inactive_file(CreateTrackedFile(app_root, "inactive_file"));
  inactive_file.tracker.set_active(false);
  inactive_file.tracker.set_dirty(true);
  inactive_file.metadata.mutable_details()->set_title("renamed inactive file");
  inactive_file.metadata.mutable_details()->set_md5("modified_md5");

  TrackedFile new_conflict(CreateTrackedFile(app_root, "new conflict file"));
  new_conflict.tracker.set_dirty(true);
  new_conflict.metadata.mutable_details()->set_title("renamed file");

  const TrackedFile* tracked_files[] = {
    &sync_root, &app_root, &file, &inactive_file, &new_conflict
  };

  SetUpDatabaseByTrackedFiles(tracked_files, arraysize(tracked_files));
  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();

  *file.tracker.mutable_synced_details() = file.metadata.details();
  file.tracker.set_dirty(false);
  EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(file.tracker));
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();

  *inactive_file.tracker.mutable_synced_details() =
       inactive_file.metadata.details();
  inactive_file.tracker.set_dirty(false);
  inactive_file.tracker.set_active(true);
  EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(inactive_file.tracker));
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();

  *new_conflict.tracker.mutable_synced_details() =
       new_conflict.metadata.details();
  new_conflict.tracker.set_dirty(false);
  new_conflict.tracker.set_active(true);
  file.tracker.set_dirty(true);
  file.tracker.set_active(false);
  EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(new_conflict.tracker));
  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();
}

TEST_F(MetadataDatabaseTest, PopulateInitialDataTest) {
  TrackedFile sync_root(CreateTrackedSyncRoot());
  TrackedFile app_root(CreateTrackedFolder(sync_root, "app_root"));
  app_root.tracker.set_active(false);

  const TrackedFile* tracked_files[] = {
    &sync_root, &app_root
  };

  int64 largest_change_id = 42;
  scoped_ptr<google_apis::FileResource> sync_root_folder(
      CreateFileResourceFromMetadata(sync_root.metadata));
  scoped_ptr<google_apis::FileResource> app_root_folder(
      CreateFileResourceFromMetadata(app_root.metadata));

  ScopedVector<google_apis::FileResource> app_root_folders;
  app_root_folders.push_back(app_root_folder.release());

  EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
  EXPECT_EQ(SYNC_STATUS_OK, PopulateInitialData(
      largest_change_id,
      *sync_root_folder,
      app_root_folders));

  ResetTrackerID(&sync_root.tracker);
  ResetTrackerID(&app_root.tracker);
  app_root.tracker.set_parent_tracker_id(sync_root.tracker.tracker_id());

  VerifyTrackedFiles(tracked_files, arraysize(tracked_files));
  VerifyReloadConsistency();
}

}  // namespace drive_backend
}  // namespace sync_file_system
