// 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/device_local_account_external_policy_loader.h"

#include <string>
#include <utility>

#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/message_loop/message_loop_current.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/testing_browser_process.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/policy_constants.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/external_install_info.h"
#include "extensions/browser/external_provider_interface.h"
#include "extensions/browser/notification_types.h"
#include "extensions/browser/updater/extension_downloader.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/manifest.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#endif  // defined(OS_CHROMEOS)

using ::testing::Field;
using ::testing::InvokeWithoutArgs;
using ::testing::Mock;
using ::testing::StrEq;
using ::testing::_;
using extensions::ExternalInstallInfoFile;
using extensions::ExternalInstallInfoUpdateUrl;

namespace chromeos {

namespace {

const char kCacheDir[] = "cache";
const char kExtensionId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
const char kExtensionUpdateManifest[] =
    "extensions/good_v1_update_manifest.xml";
const char kExtensionCRXVersion[] = "1.0.0.0";

class MockExternalPolicyProviderVisitor
    : public extensions::ExternalProviderInterface::VisitorInterface {
 public:
  MockExternalPolicyProviderVisitor();
  virtual ~MockExternalPolicyProviderVisitor();

  MOCK_METHOD1(OnExternalExtensionFileFound,
               bool(const ExternalInstallInfoFile&));
  MOCK_METHOD2(OnExternalExtensionUpdateUrlFound,
               bool(const ExternalInstallInfoUpdateUrl&, bool));
  MOCK_METHOD1(OnExternalProviderReady,
               void(const extensions::ExternalProviderInterface* provider));
  MOCK_METHOD4(OnExternalProviderUpdateComplete,
               void(const extensions::ExternalProviderInterface*,
                    const std::vector<ExternalInstallInfoUpdateUrl>&,
                    const std::vector<ExternalInstallInfoFile>&,
                    const std::set<std::string>& removed_extensions));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyProviderVisitor);
};

MockExternalPolicyProviderVisitor::MockExternalPolicyProviderVisitor() {
}

MockExternalPolicyProviderVisitor::~MockExternalPolicyProviderVisitor() {
}

}  // namespace

class DeviceLocalAccountExternalPolicyLoaderTest : public testing::Test {
 protected:
  DeviceLocalAccountExternalPolicyLoaderTest();
  ~DeviceLocalAccountExternalPolicyLoaderTest() override;

  void SetUp() override;
  void TearDown() override;

  void VerifyAndResetVisitorCallExpectations();
  void SetForceInstallListPolicy();

  network::TestURLLoaderFactory::PendingRequest* GetPendingRequest(
      size_t index = 0) {
    if (index >= test_url_loader_factory_.pending_requests()->size())
      return nullptr;
    return &test_url_loader_factory_.pending_requests()->at(index);
  }

  content::TestBrowserThreadBundle thread_bundle_;
  base::ScopedTempDir temp_dir_;
  base::FilePath cache_dir_;
  policy::MockCloudPolicyStore store_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
      test_shared_loader_factory_;
  base::FilePath test_dir_;

  scoped_refptr<DeviceLocalAccountExternalPolicyLoader> loader_;
  MockExternalPolicyProviderVisitor visitor_;
  std::unique_ptr<extensions::ExternalProviderImpl> provider_;

  content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;

#if defined(OS_CHROMEOS)
  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
  chromeos::ScopedTestCrosSettings test_cros_settings_;
#endif // defined(OS_CHROMEOS)
};

DeviceLocalAccountExternalPolicyLoaderTest::
    DeviceLocalAccountExternalPolicyLoaderTest()
    : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
      test_shared_loader_factory_(
          base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
              &test_url_loader_factory_)) {}

DeviceLocalAccountExternalPolicyLoaderTest::
    ~DeviceLocalAccountExternalPolicyLoaderTest() {
}

void DeviceLocalAccountExternalPolicyLoaderTest::SetUp() {
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  cache_dir_ = temp_dir_.GetPath().Append(kCacheDir);
  ASSERT_TRUE(base::CreateDirectoryAndGetError(cache_dir_, NULL));
  TestingBrowserProcess::GetGlobal()->SetSharedURLLoaderFactory(
      test_shared_loader_factory_);
  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));

  loader_ = new DeviceLocalAccountExternalPolicyLoader(&store_, cache_dir_);
  provider_.reset(new extensions::ExternalProviderImpl(
      &visitor_,
      loader_,
      NULL,
      extensions::Manifest::EXTERNAL_POLICY,
      extensions::Manifest::EXTERNAL_POLICY_DOWNLOAD,
      extensions::Extension::NO_FLAGS));

  VerifyAndResetVisitorCallExpectations();
}

void DeviceLocalAccountExternalPolicyLoaderTest::TearDown() {
  TestingBrowserProcess::GetGlobal()->SetSharedURLLoaderFactory(nullptr);
}

void DeviceLocalAccountExternalPolicyLoaderTest::
    VerifyAndResetVisitorCallExpectations() {
  Mock::VerifyAndClearExpectations(&visitor_);
  EXPECT_CALL(visitor_, OnExternalExtensionFileFound(_)).Times(0);
  EXPECT_CALL(visitor_, OnExternalExtensionUpdateUrlFound(_, _)).Times(0);
  EXPECT_CALL(visitor_, OnExternalProviderReady(_))
      .Times(0);
  EXPECT_CALL(visitor_, OnExternalProviderUpdateComplete(_, _, _, _)).Times(0);
}

void DeviceLocalAccountExternalPolicyLoaderTest::SetForceInstallListPolicy() {
  std::unique_ptr<base::ListValue> forcelist(new base::ListValue);
  forcelist->AppendString("invalid");
  forcelist->AppendString(base::StringPrintf(
      "%s;%s",
      kExtensionId,
      extension_urls::GetWebstoreUpdateUrl().spec().c_str()));
  store_.policy_map_.Set(policy::key::kExtensionInstallForcelist,
                         policy::POLICY_LEVEL_MANDATORY,
                         policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
                         std::move(forcelist), nullptr);
  store_.NotifyStoreLoaded();
}

// Verifies that when the cache is not explicitly started, the loader does not
// serve any extensions, even if the force-install list policy is set or a load
// is manually requested.
TEST_F(DeviceLocalAccountExternalPolicyLoaderTest, CacheNotStarted) {
  // Set the force-install list policy.
  SetForceInstallListPolicy();

  // Manually request a load.
  loader_->StartLoading();

  EXPECT_FALSE(loader_->IsCacheRunning());
}

// Verifies that the cache can be started and stopped correctly.
TEST_F(DeviceLocalAccountExternalPolicyLoaderTest, ForceInstallListEmpty) {
  // Set an empty force-install list policy.
  store_.NotifyStoreLoaded();

  // Start the cache. Verify that the loader announces an empty extension list.
  EXPECT_CALL(visitor_, OnExternalProviderReady(provider_.get()))
      .Times(1);
  loader_->StartCache(base::ThreadTaskRunnerHandle::Get());
  base::RunLoop().RunUntilIdle();
  VerifyAndResetVisitorCallExpectations();

  // Stop the cache. Verify that the loader announces an empty extension list.
  EXPECT_CALL(visitor_, OnExternalProviderReady(provider_.get()))
      .Times(1);
  base::RunLoop run_loop;
  loader_->StopCache(run_loop.QuitClosure());
  VerifyAndResetVisitorCallExpectations();

  // Spin the loop until the cache shutdown callback is invoked. Verify that at
  // that point, no further file I/O tasks are pending.
  run_loop.Run();
  EXPECT_TRUE(base::MessageLoopCurrent::Get()->IsIdleForTesting());
}

// Verifies that when a force-install list policy referencing an extension is
// set and the cache is started, the loader downloads, caches and serves the
// extension.
TEST_F(DeviceLocalAccountExternalPolicyLoaderTest, ForceInstallListSet) {
  // Set a force-install list policy that contains an invalid entry (which
  // should be ignored) and a valid reference to an extension.
  SetForceInstallListPolicy();

  // Start the cache.
  loader_->StartCache(base::ThreadTaskRunnerHandle::Get());

  // Spin the loop, allowing the loader to process the force-install list.
  // Verify that the loader announces an empty extension list.
  EXPECT_CALL(visitor_, OnExternalProviderReady(provider_.get()))
      .Times(1);
  base::RunLoop().RunUntilIdle();

  // Verify that a downloader has started and is attempting to download an
  // update manifest.
  EXPECT_EQ(1, test_url_loader_factory_.NumPending());

  // Return a manifest to the downloader.
  std::string manifest;
  EXPECT_TRUE(base::ReadFileToString(test_dir_.Append(kExtensionUpdateManifest),
                                     &manifest));

  auto* pending_request = GetPendingRequest();
  test_url_loader_factory_.AddResponse(pending_request->request.url.spec(),
                                       manifest);

  // Wait for the manifest to be parsed.
  content::WindowedNotificationObserver(
      extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
      content::NotificationService::AllSources()).Wait();

  // Verify that the downloader is attempting to download a CRX file.
  EXPECT_EQ(1, test_url_loader_factory_.NumPending());

  // Trigger downloading of the temporary CRX file.
  pending_request = GetPendingRequest();
  test_url_loader_factory_.AddResponse(pending_request->request.url.spec(),
                                       "Content is irrelevant.");

  // Spin the loop. Verify that the loader announces the presence of a new CRX
  // file, served from the cache directory.
  const base::FilePath cached_crx_path = cache_dir_.Append(base::StringPrintf(
      "%s-%s.crx", kExtensionId, kExtensionCRXVersion));
  base::RunLoop cache_run_loop;
  EXPECT_CALL(
      visitor_,
      OnExternalExtensionFileFound(AllOf(
          Field(&extensions::ExternalInstallInfoFile::extension_id,
                StrEq(kExtensionId)),
          Field(&extensions::ExternalInstallInfoFile::path, cached_crx_path),
          Field(&extensions::ExternalInstallInfoFile::crx_location,
                extensions::Manifest::EXTERNAL_POLICY))));
  EXPECT_CALL(visitor_, OnExternalProviderReady(provider_.get()))
      .Times(1)
      .WillOnce(InvokeWithoutArgs(&cache_run_loop, &base::RunLoop::Quit));
  cache_run_loop.Run();
  VerifyAndResetVisitorCallExpectations();

  // Stop the cache. Verify that the loader announces an empty extension list.
  EXPECT_CALL(visitor_, OnExternalProviderReady(provider_.get()))
      .Times(1);
  base::RunLoop shutdown_run_loop;
  loader_->StopCache(shutdown_run_loop.QuitClosure());
  VerifyAndResetVisitorCallExpectations();

  // Spin the loop until the cache shutdown callback is invoked. Verify that at
  // that point, no further file I/O tasks are pending.
  shutdown_run_loop.Run();
  EXPECT_TRUE(base::MessageLoopCurrent::Get()->IsIdleForTesting());
}

}  // namespace chromeos
