// 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 "base/files/file_path.h"
#include "chrome/browser/extensions/active_install_data.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

using extensions::ActiveInstallData;
using extensions::Extension;
using extensions::ExtensionRegistry;
using extensions::InstallTracker;
using extensions::InstallObserver;
using extensions::ScopedActiveInstall;

namespace {

// Random extension ids for testing.
const char kExtensionId1[] = "oochhailbdickimldhhodijaldpllppf";
const char kExtensionId2[] = "ahionppacfhbbmpmlcbkdgcpokfpflji";
const char kExtensionId3[] = "ladmcjmmmmgonboiadnaindoekpbljde";

scoped_refptr<Extension> CreateDummyExtension(const std::string& id) {
  base::DictionaryValue manifest;
  manifest.SetString(extensions::manifest_keys::kVersion, "1.0");
  manifest.SetString(extensions::manifest_keys::kName, "Dummy name");

  std::string error;
  scoped_refptr<Extension> extension;
  extension = Extension::Create(base::FilePath(),
                                extensions::Manifest::INTERNAL,
                                manifest,
                                Extension::NO_FLAGS,
                                id,
                                &error);
  EXPECT_TRUE(extension.get()) << "Error creating extension: " << error;
  return extension;
}

}  // namespace

class InstallTrackerTest : public testing::Test {
 public:
  InstallTrackerTest() {
    profile_.reset(new TestingProfile());
    tracker_.reset(new InstallTracker(profile_.get(), NULL));
  }

  ~InstallTrackerTest() override {}

 protected:
  Profile* profile() { return profile_.get(); }
  InstallTracker* tracker() { return tracker_.get(); }

  void VerifyInstallData(const ActiveInstallData& original,
                         const ActiveInstallData& retrieved) {
    EXPECT_EQ(original.extension_id, retrieved.extension_id);
    EXPECT_EQ(original.percent_downloaded, retrieved.percent_downloaded);
  }

  content::TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<TestingProfile> profile_;
  std::unique_ptr<InstallTracker> tracker_;
};

// Verifies that active installs are registered and deregistered correctly.
TEST_F(InstallTrackerTest, AddAndRemoveActiveInstalls) {
  ActiveInstallData install_data1(kExtensionId1);
  install_data1.percent_downloaded = 76;
  ActiveInstallData install_data2(kExtensionId2);

  tracker_->AddActiveInstall(install_data1);
  tracker_->AddActiveInstall(install_data2);

  const ActiveInstallData* retrieved_data1 =
      tracker_->GetActiveInstall(kExtensionId1);
  const ActiveInstallData* retrieved_data2 =
      tracker_->GetActiveInstall(kExtensionId2);
  const ActiveInstallData* retrieved_data3 =
      tracker_->GetActiveInstall(kExtensionId3);
  ASSERT_TRUE(retrieved_data1);
  ASSERT_TRUE(retrieved_data2);
  ASSERT_FALSE(retrieved_data3);
  VerifyInstallData(install_data1, *retrieved_data1);
  VerifyInstallData(install_data2, *retrieved_data2);
  retrieved_data1 = NULL;
  retrieved_data2 = NULL;

  tracker_->RemoveActiveInstall(kExtensionId1);
  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
  EXPECT_TRUE(tracker_->GetActiveInstall(kExtensionId2));
  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId3));
}

// Verifies that active installs are registered and deregistered correctly
// using ScopedActiveInstall.
TEST_F(InstallTrackerTest, ScopedActiveInstallDeregister) {
  // Verify the constructor that registers the install.
  ActiveInstallData install_data(kExtensionId1);
  install_data.percent_downloaded = 6;
  std::unique_ptr<ScopedActiveInstall> scoped_active_install(
      new ScopedActiveInstall(tracker(), install_data));

  const ActiveInstallData* retrieved_data =
      tracker_->GetActiveInstall(kExtensionId1);
  ASSERT_TRUE(retrieved_data);
  VerifyInstallData(install_data, *retrieved_data);
  retrieved_data = NULL;

  scoped_active_install.reset();
  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));

  // Verify the constructor that doesn't register the install.
  scoped_active_install.reset(
      new ScopedActiveInstall(tracker(), kExtensionId1));
  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));

  tracker_->AddActiveInstall(install_data);
  EXPECT_TRUE(tracker_->GetActiveInstall(kExtensionId1));

  scoped_active_install.reset();
  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
}

// Verifies that ScopedActiveInstall can be cancelled.
TEST_F(InstallTrackerTest, ScopedActiveInstallCancelled) {
  ActiveInstallData install_data(kExtensionId1);
  install_data.percent_downloaded = 87;
  std::unique_ptr<ScopedActiveInstall> scoped_active_install(
      new ScopedActiveInstall(tracker(), install_data));

  const ActiveInstallData* retrieved_data =
      tracker_->GetActiveInstall(kExtensionId1);
  ASSERT_TRUE(retrieved_data);
  VerifyInstallData(install_data, *retrieved_data);
  retrieved_data = NULL;

  scoped_active_install->CancelDeregister();
  scoped_active_install.reset();

  retrieved_data = tracker_->GetActiveInstall(kExtensionId1);
  ASSERT_TRUE(retrieved_data);
  VerifyInstallData(install_data, *retrieved_data);
}

// Verifies that the download progress is updated correctly.
TEST_F(InstallTrackerTest, DownloadProgressUpdated) {
  ActiveInstallData install_data(kExtensionId1);
  tracker_->AddActiveInstall(install_data);

  const ActiveInstallData* retrieved_data =
      tracker_->GetActiveInstall(kExtensionId1);
  ASSERT_TRUE(retrieved_data);
  EXPECT_EQ(0, retrieved_data->percent_downloaded);

  const int kUpdatedDownloadProgress = 23;
  tracker_->OnDownloadProgress(kExtensionId1, kUpdatedDownloadProgress);

  retrieved_data = tracker_->GetActiveInstall(kExtensionId1);
  ASSERT_TRUE(retrieved_data);
  EXPECT_EQ(kUpdatedDownloadProgress, retrieved_data->percent_downloaded);
}

// Verifies that OnBeginExtensionInstall() registers an active install and
// OnInstallFailure() removes an active install.
TEST_F(InstallTrackerTest, ExtensionInstallFailure) {
  InstallObserver::ExtensionInstallParams install_params(
      kExtensionId1, std::string(), gfx::ImageSkia(), false, false);
  tracker_->OnBeginExtensionInstall(install_params);

  const ActiveInstallData* retrieved_data =
      tracker_->GetActiveInstall(kExtensionId1);
  ASSERT_TRUE(retrieved_data);
  EXPECT_EQ(0, retrieved_data->percent_downloaded);
  EXPECT_EQ(install_params.extension_id, retrieved_data->extension_id);
  retrieved_data = NULL;

  tracker_->OnInstallFailure(kExtensionId1);
  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
}

// Verifies that OnExtensionInstalled() notification removes an active install.
TEST_F(InstallTrackerTest, ExtensionInstalledEvent) {
  InstallObserver::ExtensionInstallParams install_params(
      kExtensionId1, std::string(), gfx::ImageSkia(), false, false);
  tracker_->OnBeginExtensionInstall(install_params);

  const ActiveInstallData* retrieved_data =
      tracker_->GetActiveInstall(kExtensionId1);
  ASSERT_TRUE(retrieved_data);
  EXPECT_EQ(0, retrieved_data->percent_downloaded);
  EXPECT_EQ(install_params.extension_id, retrieved_data->extension_id);
  retrieved_data = NULL;

  // Simulate an extension install.
  scoped_refptr<Extension> extension = CreateDummyExtension(kExtensionId1);
  ASSERT_TRUE(extension.get());
  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  ASSERT_TRUE(registry);
  registry->AddEnabled(extension);
  registry->TriggerOnInstalled(extension.get(), false);

  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
}
