// Copyright 2016 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/extensions/chrome_test_extension_loader.h"

#include <memory>

#include "base/files/file_util.h"
#include "base/run_loop.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/extensions/chrome_extension_test_notification_observer.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/unpacked_installer.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_creator.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/notification_types.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/test/extension_test_notification_observer.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

ChromeTestExtensionLoader::ChromeTestExtensionLoader(
    content::BrowserContext* browser_context)
    : browser_context_(browser_context),
      extension_system_(ExtensionSystem::Get(browser_context)),
      extension_service_(extension_system_->extension_service()),
      extension_registry_(ExtensionRegistry::Get(browser_context)) {}

ChromeTestExtensionLoader::~ChromeTestExtensionLoader() {
  // If there was a temporary directory created for a CRX, we need to clean it
  // up before the member is destroyed so we can explicitly allow IO.
  base::ScopedAllowBlockingForTesting allow_blocking;
  if (temp_dir_.IsValid())
    EXPECT_TRUE(temp_dir_.Delete());
}

scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadExtension(
    const base::FilePath& path) {
  scoped_refptr<const Extension> extension;
  if (path.MatchesExtension(FILE_PATH_LITERAL(".crx"))) {
    extension = LoadCrx(path);
  } else if (pack_extension_) {
    base::FilePath crx_path = PackExtension(path);
    if (crx_path.empty())
      return nullptr;
    extension = LoadCrx(crx_path);
  } else {
    extension = LoadUnpacked(path);
  }

  if (should_fail_ && extension)
    ADD_FAILURE() << "Expected extension load failure, but succeeded";
  else if (!should_fail_ && !extension)
    ADD_FAILURE() << "Failed to load extension";

  if (!extension)
    return nullptr;

  extension_id_ = extension->id();
  // Trying to reload a shared module (as we do when adjusting extension
  // permissions) causes ExtensionService to crash. Only adjust permissions for
  // non-shared modules.
  // TODO(devlin): That's not good; we shouldn't be crashing.
  if (!SharedModuleInfo::IsSharedModule(extension.get())) {
    CheckPermissions(extension.get());
    // Make |extension| null since it may have been reloaded invalidating
    // pointers to it.
    extension = nullptr;
  }

  if (!install_param_.empty()) {
    ExtensionPrefs::Get(browser_context_)
        ->SetInstallParam(extension_id_, install_param_);
    // Reload the extension so listeners of the loaded notification have access
    // to the install param.
    TestExtensionRegistryObserver registry_observer(extension_registry_,
                                                    extension_id_);
    extension_service_->ReloadExtension(extension_id_);
    registry_observer.WaitForExtensionLoaded();
  }

  extension = extension_registry_->enabled_extensions().GetByID(extension_id_);
  if (!extension)
    return nullptr;
  if (!CheckInstallWarnings(*extension))
    return nullptr;

  base::RunLoop().RunUntilIdle();
  if (!WaitForExtensionReady()) {
    ADD_FAILURE() << "Failed to wait for extension ready";
    return nullptr;
  }
  return extension;
}

bool ChromeTestExtensionLoader::WaitForExtensionReady() {
  return ChromeExtensionTestNotificationObserver(browser_context_)
      .WaitForExtensionViewsToLoad();
}

base::FilePath ChromeTestExtensionLoader::PackExtension(
    const base::FilePath& unpacked_path) {
  base::ScopedAllowBlockingForTesting allow_blocking;
  if (!base::PathExists(unpacked_path)) {
    ADD_FAILURE() << "Unpacked path does not exist: " << unpacked_path.value();
    return base::FilePath();
  }

  if (!temp_dir_.CreateUniqueTempDir()) {
    ADD_FAILURE() << "Could not create unique temp dir.";
    return base::FilePath();
  }
  base::FilePath crx_path = temp_dir_.GetPath().AppendASCII("temp.crx");
  if (base::PathExists(crx_path)) {
    ADD_FAILURE() << "Crx path exists: " << crx_path.value()
        << ", are you trying to reuse the same ChromeTestExtensionLoader?";
    return base::FilePath();
  }
  base::FilePath fallback_pem_path =
      temp_dir_.GetPath().AppendASCII("temp.pem");
  if (base::PathExists(fallback_pem_path)) {
    ADD_FAILURE() << "PEM path exists: " << fallback_pem_path.value()
        << ", are you trying to reuse the same ChromeTestExtensionLoader?";
    return base::FilePath();
  }

  base::FilePath empty_path;
  base::FilePath* pem_path_to_use = &empty_path;
  if (!pem_path_.empty()) {
    pem_path_to_use = &pem_path_;
    if (!base::PathExists(pem_path_)) {
      ADD_FAILURE() << "Provided PEM path does not exist: "
                    << pem_path_.value();
      return base::FilePath();
    }
  }

  ExtensionCreator creator;
  if (!creator.Run(unpacked_path, crx_path, *pem_path_to_use, fallback_pem_path,
                   ExtensionCreator::kOverwriteCRX)) {
    ADD_FAILURE() << "ExtensionCreator::Run() failed: "
                  << creator.error_message();
    return base::FilePath();
  }

  CHECK(base::PathExists(crx_path));

  return crx_path;
}

scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadCrx(
    const base::FilePath& file_path) {
  if (!file_path.MatchesExtension(FILE_PATH_LITERAL(".crx"))) {
    ADD_FAILURE() << "Must pass a crx path to LoadCrx()";
    return nullptr;
  }

  scoped_refptr<const Extension> extension;
  {
    // TODO(devlin): Allow consumers to specify the install ui type.
    std::unique_ptr<ExtensionInstallPrompt> install_ui;
    scoped_refptr<CrxInstaller> installer =
        CrxInstaller::Create(extension_service_, std::move(install_ui));
    installer->set_expected_id(expected_id_);
    installer->set_creation_flags(creation_flags_);
    installer->set_install_source(location_);
    installer->set_install_immediately(install_immediately_);
    installer->set_allow_silent_install(grant_permissions_);
    if (!installer->is_gallery_install()) {
      installer->set_off_store_install_allow_reason(
          CrxInstaller::OffStoreInstallAllowedInTest);
    }

    content::WindowedNotificationObserver install_observer(
        NOTIFICATION_CRX_INSTALLER_DONE,
        content::Source<CrxInstaller>(installer.get()));
    installer->InstallCrx(file_path);
    install_observer.Wait();

    extension =
        content::Details<const Extension>(install_observer.details()).ptr();
  }

  return extension;
}

void ChromeTestExtensionLoader::CheckPermissions(const Extension* extension) {
  std::string id = extension->id();

  // If the client explicitly set |allow_file_access_|, use that value. Else
  // use the default as per the extensions manifest location.
  if (!allow_file_access_) {
    allow_file_access_ =
        Manifest::ShouldAlwaysAllowFileAccess(extension->location());
  }

  // |extension| may be reloaded subsequently, invalidating the pointer. Hence
  // make it null.
  extension = nullptr;

  // Toggling incognito or file access will reload the extension, so wait for
  // the reload.
  if (*allow_file_access_ != util::AllowFileAccess(id, browser_context_)) {
    TestExtensionRegistryObserver registry_observer(extension_registry_, id);
    util::SetAllowFileAccess(id, browser_context_, *allow_file_access_);
    registry_observer.WaitForExtensionLoaded();
  }

  if (allow_incognito_access_ !=
      util::IsIncognitoEnabled(id, browser_context_)) {
    TestExtensionRegistryObserver registry_observer(extension_registry_, id);
    util::SetIsIncognitoEnabled(id, browser_context_, true);
    registry_observer.WaitForExtensionLoaded();
  }
}

scoped_refptr<const Extension> ChromeTestExtensionLoader::LoadUnpacked(
    const base::FilePath& file_path) {
  const Extension* extension = nullptr;
  TestExtensionRegistryObserver registry_observer(extension_registry_);
  scoped_refptr<UnpackedInstaller> installer =
      UnpackedInstaller::Create(extension_service_);
  installer->set_require_modern_manifest_version(
      require_modern_manifest_version_);
  installer->Load(file_path);
  if (!should_fail_) {
    extension = registry_observer.WaitForExtensionLoaded();
  } else {
    EXPECT_TRUE(ExtensionTestNotificationObserver(browser_context_)
                    .WaitForExtensionLoadError())
        << "No load error observed";
  }

  return extension;
}

bool ChromeTestExtensionLoader::CheckInstallWarnings(
    const Extension& extension) {
  if (ignore_manifest_warnings_)
    return true;
  const std::vector<InstallWarning>& install_warnings =
      extension.install_warnings();
  if (install_warnings.empty())
    return true;

  std::string install_warnings_message = "Unexpected warnings for extension:\n";
  for (const InstallWarning& warning : install_warnings)
    install_warnings_message += "  " + warning.message + "\n";

  ADD_FAILURE() << install_warnings_message;
  return false;
}

}  // namespace extensions
