// 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.

#ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
#define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_

#include <string>

#include "base/macros.h"
#include "base/scoped_observer.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "extensions/browser/api/runtime/runtime_api_delegate.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_manager_observer.h"
#include "extensions/browser/update_observer.h"
#include "extensions/common/api/runtime.h"

namespace base {
class Version;
}

namespace content {
class BrowserContext;
}

class PrefRegistrySimple;

namespace extensions {

namespace api {
namespace runtime {
struct PlatformInfo;
}
}

class Extension;
class ExtensionHost;
class ExtensionRegistry;

// Runtime API dispatches onStartup, onInstalled, and similar events to
// extensions. There is one instance shared between a browser context and
// its related incognito instance.
class RuntimeAPI : public BrowserContextKeyedAPI,
                   public ExtensionRegistryObserver,
                   public UpdateObserver,
                   public ProcessManagerObserver {
 public:
  // The status of the restartAfterDelay request.
  enum class RestartAfterDelayStatus {
    // The request was made by a different extension other than the first one to
    // invoke the restartAfterDelay runtime API.
    FAILED_NOT_FIRST_EXTENSION,

    // The request came too soon after a previous restart induced by the
    // restartAfterDelay API. It failed to be scheduled as requested, and was
    // instead throttled.
    FAILED_THROTTLED,

    // Any previously scheduled restart was successfully canceled.
    SUCCESS_RESTART_CANCELED,

    // A restart was successfully scheduled.
    SUCCESS_RESTART_SCHEDULED,
  };

  static BrowserContextKeyedAPIFactory<RuntimeAPI>* GetFactoryInstance();

  static void RegisterPrefs(PrefRegistrySimple* registry);

  explicit RuntimeAPI(content::BrowserContext* context);
  ~RuntimeAPI() override;

  void ReloadExtension(const std::string& extension_id);
  bool CheckForUpdates(const std::string& extension_id,
                       const RuntimeAPIDelegate::UpdateCheckCallback& callback);
  void OpenURL(const GURL& uninstall_url);
  bool GetPlatformInfo(api::runtime::PlatformInfo* info);
  bool RestartDevice(std::string* error_message);

  RestartAfterDelayStatus RestartDeviceAfterDelay(
      const std::string& extension_id,
      int seconds_from_now);

  bool OpenOptionsPage(const Extension* extension,
                       content::BrowserContext* browser_context);

 private:
  friend class BrowserContextKeyedAPIFactory<RuntimeAPI>;
  friend class RestartAfterDelayApiTest;

  // ExtensionRegistryObserver implementation.
  void OnExtensionLoaded(content::BrowserContext* browser_context,
                         const Extension* extension) override;
  void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
                                  const Extension* extension,
                                  bool is_update,
                                  const std::string& old_name) override;
  void OnExtensionUninstalled(content::BrowserContext* browser_context,
                              const Extension* extension,
                              UninstallReason reason) override;

  // Cancels any previously scheduled restart request.
  void MaybeCancelRunningDelayedRestartTimer();

  // Handler for the signal from ExtensionSystem::ready().
  void OnExtensionsReady();

  RestartAfterDelayStatus ScheduleDelayedRestart(const base::Time& now,
                                                 int seconds_from_now);

  // Called when the delayed restart timer times out so that it attempts to
  // execute the restart request scheduled earlier.
  void OnDelayedRestartTimerTimeout();

  // BrowserContextKeyedAPI implementation:
  static const char* service_name() { return "RuntimeAPI"; }
  static const bool kServiceRedirectedInIncognito = true;
  static const bool kServiceIsNULLWhileTesting = true;
  void Shutdown() override;

  // extensions::UpdateObserver overrides:
  void OnAppUpdateAvailable(const Extension* extension) override;
  void OnChromeUpdateAvailable() override;

  // ProcessManagerObserver implementation:
  void OnBackgroundHostStartup(const Extension* extension) override;

  // Pref related functions that deals with info about installed extensions that
  // has not been loaded yet.
  // Used to send chrome.runtime.onInstalled event upon loading the extensions.
  bool ReadPendingOnInstallInfoFromPref(const ExtensionId& extension_id,
                                        base::Version* previous_version);
  void RemovePendingOnInstallInfoFromPref(const ExtensionId& extension_id);
  void StorePendingOnInstallInfoToPref(const Extension* extension);

  void AllowNonKioskAppsInRestartAfterDelayForTesting();

  void set_min_duration_between_restarts_for_testing(base::TimeDelta delta) {
    minimum_duration_between_restarts_ = delta;
  }

  std::unique_ptr<RuntimeAPIDelegate> delegate_;

  content::BrowserContext* browser_context_;

  content::NotificationRegistrar registrar_;

  // Listen to extension notifications.
  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
      extension_registry_observer_;
  ScopedObserver<ProcessManager, ProcessManagerObserver>
      process_manager_observer_;

  // The ID of the first extension to call the restartAfterDelay API. Any other
  // extensions to call this API after that will fail.
  std::string schedule_restart_first_extension_id_;

  // The timer that will trigger a device restart when it times out.
  base::OneShotTimer restart_after_delay_timer_;

  // The minimum allowed duration between two successive restarts caused by
  // restartAfterDelay calls.
  base::TimeDelta minimum_duration_between_restarts_;

  // The last restart time which was a result of a successful call to
  // chrome.runtime.restartAfterDelay().
  base::Time last_delayed_restart_time_;

  // True if we should dispatch the chrome.runtime.onInstalled event with
  // reason "chrome_update" upon loading each extension.
  bool dispatch_chrome_updated_event_;

  bool did_read_delayed_restart_preferences_;
  bool was_last_restart_due_to_delayed_restart_api_;

  base::WeakPtrFactory<RuntimeAPI> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(RuntimeAPI);
};

template <>
void BrowserContextKeyedAPIFactory<RuntimeAPI>::DeclareFactoryDependencies();

class RuntimeEventRouter {
 public:
  // Dispatches the onStartup event to all currently-loaded extensions.
  static void DispatchOnStartupEvent(content::BrowserContext* context,
                                     const std::string& extension_id);

  // Dispatches the onInstalled event to the given extension.
  static void DispatchOnInstalledEvent(content::BrowserContext* context,
                                       const std::string& extension_id,
                                       const base::Version& old_version,
                                       bool chrome_updated);

  // Dispatches the onUpdateAvailable event to the given extension.
  static void DispatchOnUpdateAvailableEvent(
      content::BrowserContext* context,
      const std::string& extension_id,
      const base::DictionaryValue* manifest);

  // Dispatches the onBrowserUpdateAvailable event to all extensions.
  static void DispatchOnBrowserUpdateAvailableEvent(
      content::BrowserContext* context);

  // Dispatches the onRestartRequired event to the given app.
  static void DispatchOnRestartRequiredEvent(
      content::BrowserContext* context,
      const std::string& app_id,
      api::runtime::OnRestartRequiredReason reason);

  // Does any work needed at extension uninstall (e.g. load uninstall url).
  static void OnExtensionUninstalled(content::BrowserContext* context,
                                     const std::string& extension_id,
                                     UninstallReason reason);
};

class RuntimeGetBackgroundPageFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.getBackgroundPage",
                             RUNTIME_GETBACKGROUNDPAGE)

 protected:
  ~RuntimeGetBackgroundPageFunction() override {}
  ResponseAction Run() override;

 private:
  void OnPageLoaded(ExtensionHost*);
};

class RuntimeOpenOptionsPageFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.openOptionsPage", RUNTIME_OPENOPTIONSPAGE)

 protected:
  ~RuntimeOpenOptionsPageFunction() override {}
  ResponseAction Run() override;
};

class RuntimeSetUninstallURLFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.setUninstallURL", RUNTIME_SETUNINSTALLURL)

 protected:
  ~RuntimeSetUninstallURLFunction() override {}
  ResponseAction Run() override;
};

class RuntimeReloadFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.reload", RUNTIME_RELOAD)

 protected:
  ~RuntimeReloadFunction() override {}
  ResponseAction Run() override;
};

class RuntimeRequestUpdateCheckFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.requestUpdateCheck",
                             RUNTIME_REQUESTUPDATECHECK)

 protected:
  ~RuntimeRequestUpdateCheckFunction() override {}
  ResponseAction Run() override;

 private:
  void CheckComplete(const RuntimeAPIDelegate::UpdateCheckResult& result);
};

class RuntimeRestartFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.restart", RUNTIME_RESTART)

 protected:
  ~RuntimeRestartFunction() override {}
  ResponseAction Run() override;
};

class RuntimeRestartAfterDelayFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.restartAfterDelay",
                             RUNTIME_RESTARTAFTERDELAY)

 protected:
  ~RuntimeRestartAfterDelayFunction() override {}
  ResponseAction Run() override;
};

class RuntimeGetPlatformInfoFunction : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.getPlatformInfo",
                             RUNTIME_GETPLATFORMINFO);

 protected:
  ~RuntimeGetPlatformInfoFunction() override {}
  ResponseAction Run() override;
};

class RuntimeGetPackageDirectoryEntryFunction
    : public UIThreadExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("runtime.getPackageDirectoryEntry",
                             RUNTIME_GETPACKAGEDIRECTORYENTRY)

 protected:
  ~RuntimeGetPackageDirectoryEntryFunction() override {}
  ResponseAction Run() override;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
