// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSION_SYSTEM_H_
#define CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSION_SYSTEM_H_

#include <string>

#include "base/memory/raw_ptr.h"
#include "base/one_shot_event.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/unloaded_extension_reason.h"

class Profile;

#if BUILDFLAG(IS_CHROMEOS)
namespace extensions {
class ExtensionsPermissionsTracker;
}  // namespace extensions

namespace chromeos {
class DeviceLocalAccountManagementPolicyProvider;
class SigninScreenPolicyProvider;
}  // namespace chromeos
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace value_store {
class ValueStoreFactory;
class ValueStoreFactoryImpl;
}  // namespace value_store

namespace extensions {

class ChromeExtensionSystemSharedFactory;
class UninstallPingSender;
class InstallGate;

// The ExtensionSystem for ProfileImpl and OffTheRecordProfileImpl.
// Implementation details: non-shared services are owned by
// ChromeExtensionSystem, a KeyedService with separate incognito
// instances. A private Shared class (also a KeyedService,
// but with a shared instance for incognito) keeps the common services.
class ChromeExtensionSystem : public ExtensionSystem {
 public:
  using InstallUpdateCallback = ExtensionSystem::InstallUpdateCallback;

  explicit ChromeExtensionSystem(Profile* profile);

  ChromeExtensionSystem(const ChromeExtensionSystem&) = delete;
  ChromeExtensionSystem& operator=(const ChromeExtensionSystem&) = delete;

  ~ChromeExtensionSystem() override;

  // KeyedService implementation.
  void Shutdown() override;

  void InitForRegularProfile(bool extensions_enabled) override;

  ExtensionService* extension_service() override;           // shared
  ManagementPolicy* management_policy() override;           // shared
  ServiceWorkerManager* service_worker_manager() override;  // shared
  UserScriptManager* user_script_manager() override;        // shared
  StateStore* state_store() override;                       // shared
  StateStore* rules_store() override;                       // shared
  StateStore* dynamic_user_scripts_store() override;        // shared
  scoped_refptr<value_store::ValueStoreFactory> store_factory()
      override;                            // shared
  QuotaService* quota_service() override;  // shared
  AppSorting* app_sorting() override;      // shared
  const base::OneShotEvent& ready() const override;
  bool is_ready() const override;
  ContentVerifier* content_verifier() override;  // shared
  std::unique_ptr<ExtensionSet> GetDependentExtensions(
      const Extension* extension) override;
  void InstallUpdate(const std::string& extension_id,
                     const std::string& public_key,
                     const base::FilePath& unpacked_dir,
                     bool install_immediately,
                     InstallUpdateCallback install_update_callback) override;
  void PerformActionBasedOnOmahaAttributes(
      const std::string& extension_id,
      const base::Value::Dict& attributes) override;

 private:
  friend class ChromeExtensionSystemSharedFactory;

  // Owns the Extension-related systems that have a single instance
  // shared between normal and incognito profiles.
  class Shared : public KeyedService {
   public:
    explicit Shared(Profile* profile);
    ~Shared() override;

    // Initialization takes place in phases.
    virtual void InitPrefs();
    // This must not be called until all the providers have been created.
    void RegisterManagementPolicyProviders();
    void InitInstallGates();
    void Init(bool extensions_enabled);

    // KeyedService implementation.
    void Shutdown() override;

    StateStore* state_store();
    StateStore* rules_store();
    StateStore* dynamic_user_scripts_store();
    scoped_refptr<value_store::ValueStoreFactory> store_factory() const;
    ExtensionService* extension_service();
    ManagementPolicy* management_policy();
    ServiceWorkerManager* service_worker_manager();
    UserScriptManager* user_script_manager();
    QuotaService* quota_service();
    AppSorting* app_sorting();
    const base::OneShotEvent& ready() const { return ready_; }
    bool is_ready() const { return ready_.is_signaled(); }
    ContentVerifier* content_verifier();

   private:
    raw_ptr<Profile> profile_;

    // The services that are shared between normal and incognito profiles.

    std::unique_ptr<StateStore> state_store_;
    std::unique_ptr<StateStore> rules_store_;
    std::unique_ptr<StateStore> dynamic_user_scripts_store_;
    scoped_refptr<value_store::ValueStoreFactoryImpl> store_factory_;
    std::unique_ptr<ServiceWorkerManager> service_worker_manager_;
    // Shared memory region manager for scripts statically declared in extension
    // manifests. This region is shared between all extensions.
    std::unique_ptr<UserScriptManager> user_script_manager_;
    // ExtensionService depends on StateStore and Blocklist.
    std::unique_ptr<ExtensionService> extension_service_;
    std::unique_ptr<ManagementPolicy> management_policy_;
    std::unique_ptr<QuotaService> quota_service_;
    std::unique_ptr<AppSorting> app_sorting_;
    std::unique_ptr<InstallGate> update_install_gate_;

    // For verifying the contents of extensions read from disk.
    scoped_refptr<ContentVerifier> content_verifier_;

    std::unique_ptr<UninstallPingSender> uninstall_ping_sender_;

#if BUILDFLAG(IS_CHROMEOS)
    std::unique_ptr<chromeos::DeviceLocalAccountManagementPolicyProvider>
        device_local_account_management_policy_provider_;
    std::unique_ptr<chromeos::SigninScreenPolicyProvider>
        signin_screen_policy_provider_;
    std::unique_ptr<InstallGate> kiosk_app_update_install_gate_;
    std::unique_ptr<ExtensionsPermissionsTracker>
        extensions_permissions_tracker_;
#endif

    base::OneShotEvent ready_;
  };

  raw_ptr<Profile> profile_;

  raw_ptr<Shared> shared_;
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSION_SYSTEM_H_
