// Copyright 2015 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 <stdint.h>

#include <string>
#include <utility>

#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/extensions/app_data_migrator.h"
#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/indexed_db_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/manifest.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_operation_runner.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/test/mock_blob_url_request_context.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
std::unique_ptr<TestingProfile> GetTestingProfile() {
  TestingProfile::Builder profile_builder;
  return profile_builder.Build();
}
}

namespace extensions {

class AppDataMigratorTest : public testing::Test {
 public:
  AppDataMigratorTest()
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}

  void SetUp() override {
    profile_ = GetTestingProfile();
    registry_ = ExtensionRegistry::Get(profile_.get());
    migrator_ = std::unique_ptr<AppDataMigrator>(
        new AppDataMigrator(profile_.get(), registry_));

    default_partition_ =
        content::BrowserContext::GetDefaultStoragePartition(profile_.get());

    idb_context_ = default_partition_->GetIndexedDBContext();

    default_fs_context_ = default_partition_->GetFileSystemContext();

    url_request_context_ = std::unique_ptr<content::MockBlobURLRequestContext>(
        new content::MockBlobURLRequestContext());
  }

  void TearDown() override {}

 protected:
  content::TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<TestingProfile> profile_;
  std::unique_ptr<AppDataMigrator> migrator_;
  content::StoragePartition* default_partition_;
  ExtensionRegistry* registry_;
  storage::FileSystemContext* default_fs_context_;
  content::IndexedDBContext* idb_context_;
  std::unique_ptr<content::MockBlobURLRequestContext> url_request_context_;
};

scoped_refptr<const Extension> GetTestExtension(bool platform_app) {
  scoped_refptr<const Extension> app;
  if (platform_app) {
    app = ExtensionBuilder()
              .SetManifest(
                  DictionaryBuilder()
                      .Set("name", "test app")
                      .Set("version", "1")
                      .Set("app", DictionaryBuilder()
                                      .Set("background",
                                           DictionaryBuilder()
                                               .Set("scripts",
                                                    ListBuilder()
                                                        .Append("background.js")
                                                        .Build())
                                               .Build())
                                      .Build())
                      .Set("permissions",
                           ListBuilder().Append("unlimitedStorage").Build())
                      .Build())
              .Build();
  } else {
    app = ExtensionBuilder()
              .SetManifest(
                  DictionaryBuilder()
                      .Set("name", "test app")
                      .Set("version", "1")
                      .Set("app", DictionaryBuilder()
                                      .Set("launch",
                                           DictionaryBuilder()
                                               .Set("local_path", "index.html")
                                               .Build())
                                      .Build())
                      .Set("permissions",
                           ListBuilder().Append("unlimitedStorage").Build())
                      .Build())
              .Build();
  }
  return app;
}

void MigrationCallback() {
}

void DidWrite(base::File::Error status, int64_t bytes, bool complete) {
  base::RunLoop::QuitCurrentWhenIdleDeprecated();
}

void DidCreate(base::File::Error status) {
}

void DidOpenFileSystem(const GURL& root,
                       const std::string& name,
                       base::File::Error result) {
}

void OpenFileSystems(storage::FileSystemContext* fs_context,
                     GURL extension_url) {
  fs_context->OpenFileSystem(extension_url, storage::kFileSystemTypeTemporary,
                             storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
                             base::BindOnce(&DidOpenFileSystem));

  fs_context->OpenFileSystem(extension_url, storage::kFileSystemTypePersistent,
                             storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
                             base::BindOnce(&DidOpenFileSystem));
  content::RunAllTasksUntilIdle();
}

void GenerateTestFiles(content::MockBlobURLRequestContext* url_request_context,
                       const Extension* ext,
                       storage::FileSystemContext* fs_context,
                       Profile* profile) {
  profile->GetExtensionSpecialStoragePolicy()->GrantRightsForExtension(ext,
                                                                       profile);

  base::FilePath path(FILE_PATH_LITERAL("test.txt"));
  GURL extension_url =
      extensions::Extension::GetBaseURLFromExtensionId(ext->id());

  OpenFileSystems(fs_context, extension_url);

  storage::FileSystemURL fs_temp_url = fs_context->CreateCrackedFileSystemURL(
      extension_url, storage::kFileSystemTypeTemporary, path);

  storage::FileSystemURL fs_persistent_url =
      fs_context->CreateCrackedFileSystemURL(
          extension_url, storage::kFileSystemTypePersistent, path);

  content::ScopedTextBlob blob1(*url_request_context, "blob-id:success1",
                                "Hello, world!\n");

  fs_context->operation_runner()->CreateFile(fs_temp_url, false,
                                             base::Bind(&DidCreate));

  fs_context->operation_runner()->CreateFile(fs_persistent_url, false,
                                             base::Bind(&DidCreate));
  content::RunAllTasksUntilIdle();

  fs_context->operation_runner()->Write(fs_temp_url, blob1.GetBlobDataHandle(),
                                        0, base::BindRepeating(&DidWrite));
  content::RunAllTasksUntilIdle();
  fs_context->operation_runner()->Write(fs_persistent_url,
                                        blob1.GetBlobDataHandle(), 0,
                                        base::BindRepeating(&DidWrite));
  content::RunAllTasksUntilIdle();
}

void VerifyFileContents(base::File file, base::OnceClosure on_close_callback) {
  ASSERT_EQ(14, file.GetLength());
  std::unique_ptr<char[]> buffer(new char[15]);

  file.Read(0, buffer.get(), 14);
  buffer.get()[14] = 0;

  std::string expected = "Hello, world!\n";
  std::string actual = buffer.get();
  EXPECT_EQ(expected, actual);

  file.Close();
  if (!on_close_callback.is_null())
    std::move(on_close_callback).Run();
  base::RunLoop::QuitCurrentWhenIdleDeprecated();
}

void VerifyTestFilesMigrated(content::StoragePartition* new_partition,
                             const Extension* new_ext) {
  GURL extension_url =
      extensions::Extension::GetBaseURLFromExtensionId(new_ext->id());
  storage::FileSystemContext* new_fs_context =
      new_partition->GetFileSystemContext();

  OpenFileSystems(new_fs_context, extension_url);

  base::FilePath path(FILE_PATH_LITERAL("test.txt"));

  storage::FileSystemURL fs_temp_url =
      new_fs_context->CreateCrackedFileSystemURL(
          extension_url, storage::kFileSystemTypeTemporary, path);
  storage::FileSystemURL fs_persistent_url =
      new_fs_context->CreateCrackedFileSystemURL(
          extension_url, storage::kFileSystemTypePersistent, path);

  new_fs_context->operation_runner()->OpenFile(
      fs_temp_url, base::File::FLAG_READ | base::File::FLAG_OPEN,
      base::Bind(&VerifyFileContents));
  content::RunAllTasksUntilIdle();
  new_fs_context->operation_runner()->OpenFile(
      fs_persistent_url, base::File::FLAG_READ | base::File::FLAG_OPEN,
      base::Bind(&VerifyFileContents));
  content::RunAllTasksUntilIdle();
}

TEST_F(AppDataMigratorTest, ShouldMigrate) {
  scoped_refptr<const Extension> old_ext = GetTestExtension(false);
  scoped_refptr<const Extension> new_ext = GetTestExtension(true);

  EXPECT_TRUE(AppDataMigrator::NeedsMigration(old_ext.get(), new_ext.get()));
}

TEST_F(AppDataMigratorTest, ShouldNotMigratePlatformApp) {
  scoped_refptr<const Extension> old_ext = GetTestExtension(true);
  scoped_refptr<const Extension> new_ext = GetTestExtension(true);

  EXPECT_FALSE(AppDataMigrator::NeedsMigration(old_ext.get(), new_ext.get()));
}

TEST_F(AppDataMigratorTest, ShouldNotMigrateLegacyApp) {
  scoped_refptr<const Extension> old_ext = GetTestExtension(false);
  scoped_refptr<const Extension> new_ext = GetTestExtension(false);

  EXPECT_FALSE(AppDataMigrator::NeedsMigration(old_ext.get(), new_ext.get()));
}

TEST_F(AppDataMigratorTest, NoOpMigration) {
  scoped_refptr<const Extension> old_ext = GetTestExtension(false);
  scoped_refptr<const Extension> new_ext = GetTestExtension(true);

  // Nothing to migrate. Basically this should just not cause an error
  migrator_->DoMigrationAndReply(old_ext.get(), new_ext.get(),
                                 base::Bind(&MigrationCallback));
}

// crbug.com/747589
TEST_F(AppDataMigratorTest, DISABLED_FileSystemMigration) {
  scoped_refptr<const Extension> old_ext = GetTestExtension(false);
  scoped_refptr<const Extension> new_ext = GetTestExtension(true);

  GenerateTestFiles(url_request_context_.get(), old_ext.get(),
                    default_fs_context_, profile_.get());

  migrator_->DoMigrationAndReply(old_ext.get(), new_ext.get(),
                                 base::Bind(&MigrationCallback));

  content::RunAllTasksUntilIdle();

  registry_->AddEnabled(new_ext);
  GURL extension_url =
      extensions::Extension::GetBaseURLFromExtensionId(new_ext->id());

  content::StoragePartition* new_partition =
      content::BrowserContext::GetStoragePartitionForSite(profile_.get(),
                                                          extension_url);

  ASSERT_NE(new_partition->GetPath(), default_partition_->GetPath());

  VerifyTestFilesMigrated(new_partition, new_ext.get());

  // Clean up.
  content::RunAllTasksUntilIdle();
}

}  // namespace extensions
