// Copyright 2018 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 "extensions/shell/browser/shell_extension_loader.h"

#include <memory>
#include <string>

#include "apps/app_lifetime_monitor_factory.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "components/crx_file/id_util.h"
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extensions_test.h"
#include "extensions/browser/mock_extension_system.h"
#include "extensions/browser/null_app_sorting.h"
#include "extensions/browser/runtime_data.h"
#include "extensions/browser/test_event_router.h"
#include "extensions/browser/test_extensions_browser_client.h"
#include "extensions/common/api/app_runtime.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/extension_paths.h"
#include "extensions/test/test_extension_dir.h"

#if defined(USE_AURA)
#include "extensions/browser/app_window/app_window.h"
#include "extensions/shell/browser/shell_app_window_client.h"
#include "extensions/shell/browser/shell_native_app_window_aura.h"
#include "extensions/shell/test/shell_test_extensions_browser_client.h"
#include "extensions/shell/test/shell_test_helper_aura.h"
#endif

namespace extensions {

namespace OnLaunched = api::app_runtime::OnLaunched;

namespace {

class TestExtensionSystem : public MockExtensionSystem {
 public:
  explicit TestExtensionSystem(content::BrowserContext* context)
      : MockExtensionSystem(context),
        runtime_data_(ExtensionRegistry::Get(context)) {}
  ~TestExtensionSystem() override = default;

  RuntimeData* runtime_data() override { return &runtime_data_; }
  AppSorting* app_sorting() override { return &app_sorting_; }

 private:
  RuntimeData runtime_data_;
  NullAppSorting app_sorting_;

  DISALLOW_COPY_AND_ASSIGN(TestExtensionSystem);
};

#if defined(USE_AURA)
// An AppWindowClient for use without a DesktopController.
class TestAppWindowClient : public ShellAppWindowClient {
 public:
  TestAppWindowClient() = default;
  ~TestAppWindowClient() override = default;

  // ShellAppWindowClient:
  NativeAppWindow* CreateNativeAppWindow(
      AppWindow* window,
      AppWindow::CreateParams* params) override {
    return new ShellNativeAppWindowAura(window, *params);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestAppWindowClient);
};
#endif

}  // namespace

class ShellExtensionLoaderTest : public ExtensionsTest {
 protected:
  ShellExtensionLoaderTest() = default;
  ~ShellExtensionLoaderTest() override = default;

  void SetUp() override {
    // Register factory so it's created with the BrowserContext.
    apps::AppLifetimeMonitorFactory::GetInstance();

    ExtensionsTest::SetUp();
    extensions_browser_client()->set_extension_system_factory(&factory_);
    // ExtensionsTest sets up the ExtensionPrefs, but we still need to attach
    // the PrefService to the browser context.
    user_prefs::UserPrefs::Set(browser_context(), pref_service());
    event_router_ = CreateAndUseTestEventRouter(browser_context());
  }

  void TearDown() override {
    EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
    ExtensionsTest::TearDown();
  }

  // Returns the path to a test directory.
  base::FilePath GetExtensionPath(const std::string& dir) {
    base::FilePath test_data_dir;
    base::PathService::Get(DIR_TEST_DATA, &test_data_dir);
    return test_data_dir.AppendASCII(dir);
  }

  // Verifies the extension is correctly created and enabled.
  void ExpectEnabled(const Extension* extension) {
    ASSERT_TRUE(extension);
    EXPECT_EQ(Manifest::COMMAND_LINE, extension->location());
    ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
    EXPECT_TRUE(registry->enabled_extensions().Contains(extension->id()));
    EXPECT_FALSE(registry->GetExtensionById(
        extension->id(),
        ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::ENABLED));
  }

  // Verifies the extension with the given ID is disabled.
  void ExpectDisabled(const ExtensionId& extension_id) {
    ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
    EXPECT_TRUE(registry->disabled_extensions().Contains(extension_id));
    EXPECT_FALSE(registry->GetExtensionById(
        extension_id,
        ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::DISABLED));
  }

  TestEventRouter* event_router() { return event_router_; }

 private:
  MockExtensionSystemFactory<TestExtensionSystem> factory_;

  TestEventRouter* event_router_ = nullptr;  // Created in SetUp().

  DISALLOW_COPY_AND_ASSIGN(ShellExtensionLoaderTest);
};

// Tests with a non-existent directory.
TEST_F(ShellExtensionLoaderTest, NotFound) {
  ShellExtensionLoader loader(browser_context());

  const Extension* extension =
      loader.LoadExtension(GetExtensionPath("nonexistent"));
  ASSERT_FALSE(extension);
  EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}

// Tests loading and reloading an extension.
TEST_F(ShellExtensionLoaderTest, Extension) {
  ShellExtensionLoader loader(browser_context());

  const Extension* extension =
      loader.LoadExtension(GetExtensionPath("extension"));
  ExpectEnabled(extension);

  // Extensions shouldn't receive the onLaunched event.
  EXPECT_EQ(0, event_router()->GetEventCount(OnLaunched::kEventName));

  // No keep-alives are used for non-app extensions.
  const ExtensionId extension_id = extension->id();
  loader.ReloadExtension(extension->id());
  ExpectDisabled(extension_id);
  EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  // Wait for load.
  content::RunAllTasksUntilIdle();
  extension = ExtensionRegistry::Get(browser_context())
                  ->GetInstalledExtension(extension_id);
  ExpectEnabled(extension);
  EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  // Not an app.
  EXPECT_EQ(0, event_router()->GetEventCount(OnLaunched::kEventName));
}

// Tests that the extension is added as enabled even if is disabled in
// ExtensionPrefs. Unlike Chrome, AppShell doesn't have a UI surface for
// re-enabling a disabled extension.
TEST_F(ShellExtensionLoaderTest, LoadAfterReloadFailure) {
  base::FilePath extension_path = GetExtensionPath("extension");
  const ExtensionId extension_id =
      crx_file::id_util::GenerateIdForPath(extension_path);
  ExtensionPrefs::Get(browser_context())
      ->SetExtensionDisabled(extension_id, disable_reason::DISABLE_RELOAD);

  ShellExtensionLoader loader(browser_context());
  const Extension* extension = loader.LoadExtension(extension_path);
  ExpectEnabled(extension);
}

// Tests that the extension is not added if it is disabled in ExtensionPrefs
// for reasons beyond reloading.
TEST_F(ShellExtensionLoaderTest, LoadDisabledExtension) {
  base::FilePath extension_path = GetExtensionPath("extension");
  const ExtensionId extension_id =
      crx_file::id_util::GenerateIdForPath(extension_path);
  ExtensionPrefs::Get(browser_context())
      ->SetExtensionDisabled(
          extension_id,
          disable_reason::DISABLE_RELOAD | disable_reason::DISABLE_USER_ACTION);

  ShellExtensionLoader loader(browser_context());
  const Extension* extension = loader.LoadExtension(extension_path);
  ExpectDisabled(extension->id());
}

#if defined(USE_AURA)
class ShellExtensionLoaderTestAura : public ShellExtensionLoaderTest {
 protected:
  ShellExtensionLoaderTestAura() = default;
  ~ShellExtensionLoaderTestAura() override = default;

  void SetUp() override {
    aura_helper_ = std::make_unique<ShellTestHelperAura>();
    aura_helper_->SetUp();

    std::unique_ptr<TestExtensionsBrowserClient>
        test_extensions_browser_client =
            std::make_unique<ShellTestExtensionsBrowserClient>();
    SetExtensionsBrowserClient(std::move(test_extensions_browser_client));
    AppWindowClient::Set(&app_window_client_);

    ShellExtensionLoaderTest::SetUp();
  }

  void TearDown() override {
    ShellExtensionLoaderTest::TearDown();
    AppWindowClient::Set(nullptr);
    aura_helper_->TearDown();
  }

  // Returns an initialized app window for the extension.
  // The app window deletes itself when its native window is closed.
  AppWindow* CreateAppWindow(const Extension* extension) {
    AppWindow* app_window =
        app_window_client_.CreateAppWindow(browser_context(), extension);
    aura_helper_->InitAppWindow(app_window);
    return app_window;
  }

 private:
  std::unique_ptr<ShellTestHelperAura> aura_helper_;
  TestAppWindowClient app_window_client_;

  DISALLOW_COPY_AND_ASSIGN(ShellExtensionLoaderTestAura);
};

// Tests loading and launching a platform app.
TEST_F(ShellExtensionLoaderTestAura, AppLaunch) {
  ShellExtensionLoader loader(browser_context());

  const Extension* extension =
      loader.LoadExtension(GetExtensionPath("platform_app"));
  ExpectEnabled(extension);

  // A keep-alive is waiting for the app to launch its first window.
  // (Not strictly necessary in AppShell, because DesktopWindowControllerAura
  // doesn't consider quitting until an already-open window is closed, but
  // ShellExtensionLoader and ShellKeepAliveRequester don't make that
  // assumption.)
  EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  {
    // When AppShell launches the app window, the keep-alive is removed.
    AppWindow* app_window = CreateAppWindow(extension);
    EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
    app_window->GetBaseWindow()->Close();  // Deletes |app_window|.
  }
}

// Tests loading, launching and reloading a platform app.
TEST_F(ShellExtensionLoaderTestAura, AppLaunchAndReload) {
  ShellExtensionLoader loader(browser_context());

  const Extension* extension =
      loader.LoadExtension(GetExtensionPath("platform_app"));
  const ExtensionId extension_id = extension->id();
  ExpectEnabled(extension);
  EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  CreateAppWindow(extension);
  EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  // Reload the app.
  loader.ReloadExtension(extension->id());
  ExpectDisabled(extension_id);
  EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  // Complete the reload. ShellExtensionLoader sends the onLaunched event.
  content::RunAllTasksUntilIdle();
  extension = ExtensionRegistry::Get(browser_context())
                  ->GetInstalledExtension(extension_id);
  ExpectEnabled(extension);
  EXPECT_EQ(1, event_router()->GetEventCount(OnLaunched::kEventName));
  EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  {
    // The keep-alive is destroyed when an app window is launched.
    AppWindow* app_window = CreateAppWindow(extension);
    EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

    app_window->GetBaseWindow()->Close();
  }
}

// Tests failing to reload an app.
TEST_F(ShellExtensionLoaderTestAura, ReloadFailure) {
  ShellExtensionLoader loader(browser_context());
  ExtensionId extension_id;

  // Create an extension in a temporary directory so we can delete it before
  // trying to reload it.
  {
    TestExtensionDir extension_dir;
    extension_dir.WriteManifest(
        R"({
             "name": "Test Platform App",
             "version": "1",
             "manifest_version": 2,
              "app": {
                "background": {
                  "scripts": ["background.js"]
                }
              }
           })");
    extension_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "");

    const Extension* extension =
        loader.LoadExtension(extension_dir.UnpackedPath());
    ASSERT_TRUE(extension);
    extension_id = extension->id();
    ExpectEnabled(extension);
    EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

    // Launch an app window.
    CreateAppWindow(extension);
    EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

    // Reload the app.
    loader.ReloadExtension(extension->id());
    EXPECT_TRUE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
  }

  // Wait for load (which will fail because the directory is missing).
  content::RunAllTasksUntilIdle();

  ExpectDisabled(extension_id);
  EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());

  // We can't reload an extension that is already disabled for reloading, so
  // trying to reload this extension shouldn't result in a dangling keep-alive.
  loader.ReloadExtension(extension_id);
  EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive());
}
#endif

}  // namespace extensions
