// 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/chromeos/extensions/external_cache.h"

#include <map>
#include <set>
#include <string>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/sequenced_worker_pool_owner.h"
#include "base/values.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/common/extension_urls.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const char kTestExtensionId1[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const char kTestExtensionId2[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const char kTestExtensionId3[] = "cccccccccccccccccccccccccccccccc";
const char kTestExtensionId4[] = "dddddddddddddddddddddddddddddddd";
const char kNonWebstoreUpdateUrl[] = "https://localhost/service/update2/crx";

}  // namespace

namespace chromeos {

class ExternalCacheTest : public testing::Test,
                          public ExternalCache::Delegate {
 public:
  ExternalCacheTest()
    : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {
  }
  ~ExternalCacheTest() override {}

  scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
    return background_task_runner_;
  }

  net::URLRequestContextGetter* request_context_getter() {
    return request_context_getter_.get();
  }

  const base::DictionaryValue* provided_prefs() {
    return prefs_.get();
  }

  // testing::Test overrides:
  void SetUp() override {
    request_context_getter_ = new net::TestURLRequestContextGetter(
        content::BrowserThread::GetMessageLoopProxyForThread(
            content::BrowserThread::IO));
    fetcher_factory_.reset(new net::TestURLFetcherFactory());

    pool_owner_.reset(
        new base::SequencedWorkerPoolOwner(3, "Background Pool"));
    background_task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner(
        pool_owner_->pool()->GetNamedSequenceToken("background"));
  }

  // ExternalCache::Delegate:
  void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override {
    prefs_.reset(prefs->DeepCopy());
  }

  std::string GetInstalledExtensionVersion(const std::string& id) override {
    std::map<std::string, std::string>::iterator it =
        installed_extensions_.find(id);
    return it != installed_extensions_.end() ? it->second : std::string();
  }

  base::FilePath CreateCacheDir(bool initialized) {
    EXPECT_TRUE(cache_dir_.CreateUniqueTempDir());
    if (initialized)
      CreateFlagFile(cache_dir_.path());
    return cache_dir_.path();
  }

  base::FilePath CreateTempDir() {
    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
    return temp_dir_.path();
  }

  void CreateFlagFile(const base::FilePath& dir) {
    CreateFile(dir.Append(
        extensions::LocalExtensionCache::kCacheReadyFlagFileName));
  }

  void CreateExtensionFile(const base::FilePath& dir,
                           const std::string& id,
                           const std::string& version) {
    CreateFile(GetExtensionFile(dir, id, version));
  }

  void CreateFile(const base::FilePath& file) {
    EXPECT_EQ(base::WriteFile(file, NULL, 0), 0);
  }

  base::FilePath GetExtensionFile(const base::FilePath& dir,
                                  const std::string& id,
                                  const std::string& version) {
    return dir.Append(id + "-" + version + ".crx");
  }

  base::DictionaryValue* CreateEntryWithUpdateUrl(bool from_webstore) {
    base::DictionaryValue* entry = new base::DictionaryValue;
    entry->SetString(extensions::ExternalProviderImpl::kExternalUpdateUrl,
        from_webstore ? extension_urls::GetWebstoreUpdateUrl().spec()
                      : kNonWebstoreUpdateUrl);
    return entry;
  }

  void WaitForCompletion() {
    // Wait for background task completion that sends replay to UI thread.
    pool_owner_->pool()->FlushForTesting();
    // Wait for UI thread task completion.
    base::RunLoop().RunUntilIdle();
  }

  void AddInstalledExtension(const std::string& id,
                             const std::string& version) {
    installed_extensions_[id] = version;
  }

 private:
  content::TestBrowserThreadBundle thread_bundle_;

  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
  scoped_ptr<net::TestURLFetcherFactory> fetcher_factory_;

  scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
  scoped_refptr<base::SequencedTaskRunner> background_task_runner_;

  base::ScopedTempDir cache_dir_;
  base::ScopedTempDir temp_dir_;
  scoped_ptr<base::DictionaryValue> prefs_;
  std::map<std::string, std::string> installed_extensions_;

  ScopedTestDeviceSettingsService test_device_settings_service_;
  ScopedTestCrosSettings test_cros_settings_;

  DISALLOW_COPY_AND_ASSIGN(ExternalCacheTest);
};

TEST_F(ExternalCacheTest, Basic) {
  base::FilePath cache_dir(CreateCacheDir(false));
  ExternalCache external_cache(cache_dir, request_context_getter(),
      background_task_runner(), this, true, false);

  scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
  base::DictionaryValue* dict = CreateEntryWithUpdateUrl(true);
  prefs->Set(kTestExtensionId1, dict);
  CreateExtensionFile(cache_dir, kTestExtensionId1, "1");
  dict = CreateEntryWithUpdateUrl(true);
  prefs->Set(kTestExtensionId2, dict);
  prefs->Set(kTestExtensionId3, CreateEntryWithUpdateUrl(false));
  CreateExtensionFile(cache_dir, kTestExtensionId3, "3");
  prefs->Set(kTestExtensionId4, CreateEntryWithUpdateUrl(false));

  external_cache.UpdateExtensionsList(prefs.Pass());
  WaitForCompletion();

  ASSERT_TRUE(provided_prefs());
  EXPECT_EQ(provided_prefs()->size(), 2ul);

  // File in cache from Webstore.
  const base::DictionaryValue* entry1 = NULL;
  ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId1, &entry1));
  EXPECT_FALSE(entry1->HasKey(
      extensions::ExternalProviderImpl::kExternalUpdateUrl));
  EXPECT_TRUE(entry1->HasKey(
      extensions::ExternalProviderImpl::kExternalCrx));
  EXPECT_TRUE(entry1->HasKey(
      extensions::ExternalProviderImpl::kExternalVersion));
  bool from_webstore = false;
  EXPECT_TRUE(entry1->GetBoolean(
      extensions::ExternalProviderImpl::kIsFromWebstore, &from_webstore));
  EXPECT_TRUE(from_webstore);

  // File in cache not from Webstore.
  const base::DictionaryValue* entry3 = NULL;
  ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId3, &entry3));
  EXPECT_FALSE(entry3->HasKey(
      extensions::ExternalProviderImpl::kExternalUpdateUrl));
  EXPECT_TRUE(entry3->HasKey(
      extensions::ExternalProviderImpl::kExternalCrx));
  EXPECT_TRUE(entry3->HasKey(
      extensions::ExternalProviderImpl::kExternalVersion));
  EXPECT_FALSE(entry3->HasKey(
      extensions::ExternalProviderImpl::kIsFromWebstore));

  // Update from Webstore.
  base::FilePath temp_dir(CreateTempDir());
  base::FilePath temp_file2 = temp_dir.Append("b.crx");
  CreateFile(temp_file2);
  external_cache.OnExtensionDownloadFinished(
      extensions::CRXFileInfo(kTestExtensionId2, temp_file2), true, GURL(), "2",
      extensions::ExtensionDownloaderDelegate::PingResult(), std::set<int>(),
      extensions::ExtensionDownloaderDelegate::InstallCallback());

  WaitForCompletion();
  EXPECT_EQ(provided_prefs()->size(), 3ul);

  const base::DictionaryValue* entry2 = NULL;
  ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId2, &entry2));
  EXPECT_FALSE(entry2->HasKey(
      extensions::ExternalProviderImpl::kExternalUpdateUrl));
  EXPECT_TRUE(entry2->HasKey(
      extensions::ExternalProviderImpl::kExternalCrx));
  EXPECT_TRUE(entry2->HasKey(
      extensions::ExternalProviderImpl::kExternalVersion));
  from_webstore = false;
  EXPECT_TRUE(entry2->GetBoolean(
      extensions::ExternalProviderImpl::kIsFromWebstore, &from_webstore));
  EXPECT_TRUE(from_webstore);
  EXPECT_TRUE(base::PathExists(
      GetExtensionFile(cache_dir, kTestExtensionId2, "2")));

  // Update not from Webstore.
  base::FilePath temp_file4 = temp_dir.Append("d.crx");
  CreateFile(temp_file4);
  external_cache.OnExtensionDownloadFinished(
      extensions::CRXFileInfo(kTestExtensionId4, temp_file4), true, GURL(), "4",
      extensions::ExtensionDownloaderDelegate::PingResult(), std::set<int>(),
      extensions::ExtensionDownloaderDelegate::InstallCallback());

  WaitForCompletion();
  EXPECT_EQ(provided_prefs()->size(), 4ul);

  const base::DictionaryValue* entry4 = NULL;
  ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId4, &entry4));
  EXPECT_FALSE(entry4->HasKey(
      extensions::ExternalProviderImpl::kExternalUpdateUrl));
  EXPECT_TRUE(entry4->HasKey(
      extensions::ExternalProviderImpl::kExternalCrx));
  EXPECT_TRUE(entry4->HasKey(
      extensions::ExternalProviderImpl::kExternalVersion));
  EXPECT_FALSE(entry4->HasKey(
      extensions::ExternalProviderImpl::kIsFromWebstore));
  EXPECT_TRUE(base::PathExists(
      GetExtensionFile(cache_dir, kTestExtensionId4, "4")));

  // Damaged file should be removed from disk.
  external_cache.OnDamagedFileDetected(
      GetExtensionFile(cache_dir, kTestExtensionId2, "2"));
  WaitForCompletion();
  EXPECT_EQ(provided_prefs()->size(), 3ul);
  EXPECT_FALSE(base::PathExists(
      GetExtensionFile(cache_dir, kTestExtensionId2, "2")));

  // Shutdown with callback OnExtensionListsUpdated that clears prefs.
  scoped_ptr<base::DictionaryValue> empty(new base::DictionaryValue);
  external_cache.Shutdown(
        base::Bind(&ExternalCacheTest::OnExtensionListsUpdated,
                   base::Unretained(this),
                   base::Unretained(empty.get())));
  WaitForCompletion();
  EXPECT_EQ(provided_prefs()->size(), 0ul);

  // After Shutdown directory shouldn't be touched.
  external_cache.OnDamagedFileDetected(
      GetExtensionFile(cache_dir, kTestExtensionId4, "4"));
  WaitForCompletion();
  EXPECT_TRUE(base::PathExists(
      GetExtensionFile(cache_dir, kTestExtensionId4, "4")));
}

TEST_F(ExternalCacheTest, PreserveInstalled) {
  base::FilePath cache_dir(CreateCacheDir(false));
  ExternalCache external_cache(cache_dir, request_context_getter(),
      background_task_runner(), this, true, false);

  scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
  prefs->Set(kTestExtensionId1, CreateEntryWithUpdateUrl(true));
  prefs->Set(kTestExtensionId2, CreateEntryWithUpdateUrl(true));

  AddInstalledExtension(kTestExtensionId1, "1");

  external_cache.UpdateExtensionsList(prefs.Pass());
  WaitForCompletion();

  ASSERT_TRUE(provided_prefs());
  EXPECT_EQ(provided_prefs()->size(), 1ul);

  // File not in cache but extension installed.
  const base::DictionaryValue* entry1 = NULL;
  ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId1, &entry1));
  EXPECT_TRUE(entry1->HasKey(
      extensions::ExternalProviderImpl::kExternalUpdateUrl));
  EXPECT_FALSE(entry1->HasKey(
      extensions::ExternalProviderImpl::kExternalCrx));
  EXPECT_FALSE(entry1->HasKey(
      extensions::ExternalProviderImpl::kExternalVersion));
}

}  // namespace chromeos
