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

#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "chrome/browser/drive/drive_uploader.h"
#include "chrome/browser/drive/fake_drive_service.h"
#include "chrome/browser/extensions/test_extension_service.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
#include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/value_builder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
#include "third_party/leveldatabase/src/include/leveldb/env.h"

namespace sync_file_system {
namespace drive_backend {

namespace {

const char kAppID[] = "app_id";

void EmptyTask(SyncStatusCode status, const SyncStatusCallback& callback) {
  base::MessageLoop::current()->PostTask(
      FROM_HERE, base::Bind(callback, status));
}

}  // namespace

class MockSyncTask : public ExclusiveTask {
 public:
  explicit MockSyncTask(bool used_network) {
    set_used_network(used_network);
  }
  virtual ~MockSyncTask() {}

  virtual void RunExclusive(const SyncStatusCallback& callback) OVERRIDE {
    callback.Run(SYNC_STATUS_OK);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MockSyncTask);
};

class MockExtensionService : public TestExtensionService {
 public:
  MockExtensionService() {}
  virtual ~MockExtensionService() {}

  virtual const extensions::ExtensionSet* extensions() const OVERRIDE {
    return &extensions_;
  }

  virtual void AddExtension(const extensions::Extension* extension) OVERRIDE {
    extensions_.Insert(make_scoped_refptr(extension));
  }

  virtual const extensions::Extension* GetInstalledExtension(
      const std::string& extension_id) const OVERRIDE {
    return extensions_.GetByID(extension_id);
  }

  virtual bool IsExtensionEnabled(
      const std::string& extension_id) const OVERRIDE {
    return extensions_.Contains(extension_id) &&
        !disabled_extensions_.Contains(extension_id);
  }

  void UninstallExtension(const std::string& extension_id) {
    extensions_.Remove(extension_id);
    disabled_extensions_.Remove(extension_id);
  }

  void DisableExtension(const std::string& extension_id) {
    if (!IsExtensionEnabled(extension_id))
      return;
    const extensions::Extension* extension = extensions_.GetByID(extension_id);
    disabled_extensions_.Insert(make_scoped_refptr(extension));
  }

 private:
  extensions::ExtensionSet extensions_;
  extensions::ExtensionSet disabled_extensions_;

  DISALLOW_COPY_AND_ASSIGN(MockExtensionService);
};

class SyncWorkerTest : public testing::Test,
                       public base::SupportsWeakPtr<SyncWorkerTest> {
 public:
  SyncWorkerTest() {}
  virtual ~SyncWorkerTest() {}

  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));

    extension_service_.reset(new MockExtensionService);
    scoped_ptr<drive::DriveServiceInterface>
        fake_drive_service(new drive::FakeDriveService);

    scoped_ptr<SyncEngineContext>
        sync_engine_context(new SyncEngineContext(
            fake_drive_service.Pass(),
            scoped_ptr<drive::DriveUploaderInterface>(),
            NULL /* task_logger */,
            base::ThreadTaskRunnerHandle::Get() /* ui_task_runner */,
            base::ThreadTaskRunnerHandle::Get() /* worker_task_runner */));

    sync_worker_.reset(new SyncWorker(
        profile_dir_.path(),
        extension_service_->AsWeakPtr(),
        in_memory_env_.get()));
    sync_worker_->Initialize(sync_engine_context.Pass());

    sync_worker_->SetSyncEnabled(true);
    base::RunLoop().RunUntilIdle();
  }

  virtual void TearDown() OVERRIDE {
    sync_worker_.reset();
    extension_service_.reset();
    base::RunLoop().RunUntilIdle();
  }

  MockExtensionService* extension_service() { return extension_service_.get(); }
  SyncWorker* sync_worker() { return sync_worker_.get(); }

  void UpdateRegisteredApps() {
    sync_worker_->UpdateRegisteredApps();
  }

  SyncTaskManager* GetSyncTaskManager() {
    return sync_worker_->task_manager_.get();
  }

  void CheckServiceState(SyncStatusCode expected_sync_status,
                         RemoteServiceState expected_service_status,
                         SyncStatusCode sync_status) {
    EXPECT_EQ(expected_sync_status, sync_status);
    EXPECT_EQ(expected_service_status, sync_worker_->GetCurrentState());
  }

  MetadataDatabase* metadata_database() {
    return sync_worker_->GetMetadataDatabase();
  }

 private:
  content::TestBrowserThreadBundle browser_threads_;
  base::ScopedTempDir profile_dir_;
  scoped_ptr<leveldb::Env> in_memory_env_;

  scoped_ptr<MockExtensionService> extension_service_;
  scoped_ptr<SyncWorker> sync_worker_;

  DISALLOW_COPY_AND_ASSIGN(SyncWorkerTest);
};

TEST_F(SyncWorkerTest, EnableOrigin) {
  FileTracker tracker;
  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
  GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);

  sync_worker()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
  ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID, &tracker));
  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());

  sync_worker()->DisableOrigin(origin, CreateResultReceiver(&sync_status));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
  ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID, &tracker));
  EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());

  sync_worker()->EnableOrigin(origin, CreateResultReceiver(&sync_status));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
  ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID, &tracker));
  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());

  sync_worker()->UninstallOrigin(
      origin,
      RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE,
      CreateResultReceiver(&sync_status));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
  ASSERT_FALSE(metadata_database()->FindAppRootTracker(kAppID, &tracker));
}

TEST_F(SyncWorkerTest, UpdateRegisteredApps) {
  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
  for (int i = 0; i < 3; i++) {
    scoped_refptr<const extensions::Extension> extension =
        extensions::ExtensionBuilder()
        .SetManifest(extensions::DictionaryBuilder()
                     .Set("name", "foo")
                     .Set("version", "1.0")
                     .Set("manifest_version", 2))
        .SetID(base::StringPrintf("app_%d", i))
        .Build();
    extension_service()->AddExtension(extension.get());
    GURL origin = extensions::Extension::GetBaseURLFromExtensionId(
        extension->id());
    sync_status = SYNC_STATUS_UNKNOWN;
    sync_worker()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(SYNC_STATUS_OK, sync_status);
  }

  FileTracker tracker;

  ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker));
  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());

  ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker));
  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());

  ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_2", &tracker));
  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());

  extension_service()->DisableExtension("app_1");
  extension_service()->UninstallExtension("app_2");
  ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2"));
  UpdateRegisteredApps();
  base::RunLoop().RunUntilIdle();

  ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker));
  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());

  ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker));
  EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());

  ASSERT_FALSE(metadata_database()->FindAppRootTracker("app_2", &tracker));
}

TEST_F(SyncWorkerTest, GetOriginStatusMap) {
  FileTracker tracker;
  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
  GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);

  sync_worker()->RegisterOrigin(GURL("chrome-extension://app_0"),
                                CreateResultReceiver(&sync_status));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(SYNC_STATUS_OK, sync_status);

  sync_worker()->RegisterOrigin(GURL("chrome-extension://app_1"),
                                CreateResultReceiver(&sync_status));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(SYNC_STATUS_OK, sync_status);

  scoped_ptr<RemoteFileSyncService::OriginStatusMap> status_map;
  sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map));
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(2u, status_map->size());
  EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_0")]);
  EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_1")]);

  sync_worker()->DisableOrigin(GURL("chrome-extension://app_1"),
                               CreateResultReceiver(&sync_status));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(SYNC_STATUS_OK, sync_status);

  sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map));
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(2u, status_map->size());
  EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_0")]);
  EXPECT_EQ("Disabled", (*status_map)[GURL("chrome-extension://app_1")]);
}

TEST_F(SyncWorkerTest, UpdateServiceState) {
  EXPECT_EQ(REMOTE_SERVICE_OK, sync_worker()->GetCurrentState());

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_STATUS_AUTHENTICATION_FAILED),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_AUTHENTICATION_FAILED,
                 REMOTE_SERVICE_AUTHENTICATION_REQUIRED));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_STATUS_ACCESS_FORBIDDEN),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_ACCESS_FORBIDDEN,
                 REMOTE_SERVICE_ACCESS_FORBIDDEN));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE,
                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_STATUS_NETWORK_ERROR),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_NETWORK_ERROR,
                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_STATUS_ABORT),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_ABORT,
                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_STATUS_FAILED),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_FAILED,
                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_CORRUPTION),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_DATABASE_ERROR_CORRUPTION,
                 REMOTE_SERVICE_DISABLED));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_IO_ERROR),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_DATABASE_ERROR_IO_ERROR,
                 REMOTE_SERVICE_DISABLED));

  GetSyncTaskManager()->ScheduleTask(
      FROM_HERE,
      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_FAILED),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_DATABASE_ERROR_FAILED,
                 REMOTE_SERVICE_DISABLED));

  GetSyncTaskManager()->ScheduleSyncTask(
      FROM_HERE,
      scoped_ptr<SyncTask>(new MockSyncTask(false)),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_OK,
                 REMOTE_SERVICE_DISABLED));

  GetSyncTaskManager()->ScheduleSyncTask(
      FROM_HERE,
      scoped_ptr<SyncTask>(new MockSyncTask(true)),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&SyncWorkerTest::CheckServiceState,
                 AsWeakPtr(),
                 SYNC_STATUS_OK,
                 REMOTE_SERVICE_OK));

  base::RunLoop().RunUntilIdle();
}

}  // namespace drive_backend
}  // namespace sync_file_system
