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

#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_MANAGER_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_data_delegate.h"
#include "chrome/browser/chromeos/extensions/external_cache.h"
#include "chrome/browser/chromeos/extensions/external_cache_delegate.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chromeos/settings/install_attributes.h"
#include "components/account_id/account_id.h"
#include "ui/gfx/image/image_skia.h"

class GURL;
class PrefRegistrySimple;
class Profile;

namespace base {
class CommandLine;
}

namespace extensions {
class Extension;
}

namespace chromeos {

class AppSession;
class ExternalCache;
class KioskAppData;
class KioskAppManagerObserver;
class KioskExternalUpdater;
class OwnerSettingsServiceChromeOS;

// KioskAppManager manages cached app data.
class KioskAppManager : public KioskAppDataDelegate,
                        public ExternalCacheDelegate {
 public:
  enum ConsumerKioskAutoLaunchStatus {
    // Consumer kiosk mode auto-launch feature can be enabled on this machine.
    CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE,
    // Consumer kiosk auto-launch feature is enabled on this machine.
    CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED,
    // Consumer kiosk mode auto-launch feature is disabled and cannot any longer
    // be enabled on this machine.
    CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED,
  };

  typedef base::Callback<void(bool success)> EnableKioskAutoLaunchCallback;
  typedef base::Callback<void(ConsumerKioskAutoLaunchStatus status)>
      GetConsumerKioskAutoLaunchStatusCallback;

  // Struct to hold app info returned from GetApps() call.
  struct App {
    App(const KioskAppData& data,
        bool is_extension_pending,
        bool was_auto_launched_with_zero_delay);
    App();
    App(const App& other);
    ~App();

    std::string app_id;
    AccountId account_id;
    std::string name;
    gfx::ImageSkia icon;
    std::string required_platform_version;
    bool is_loading;
    bool was_auto_launched_with_zero_delay;
  };
  typedef std::vector<App> Apps;

  // Interface that can be used to override default KioskAppManager behavior.
  // For example, it can be used in tests to inject test components
  // implementations.
  class Overrides {
   public:
    virtual ~Overrides() = default;

    // Creates the external cache that should be used by the
    // KioskAppManager. It should always return a valid object.
    virtual std::unique_ptr<ExternalCache> CreateExternalCache(
        ExternalCacheDelegate* delegate,
        bool always_check_updates) = 0;

    // Creates an AppSession object that will mantain a started kiosk app
    // session.
    // Called when the KioskAppManager initializes the session.
    // It can return nullptr.
    virtual std::unique_ptr<AppSession> CreateAppSession() = 0;
  };

  // Name of a dictionary that holds kiosk app info in Local State.
  // Sample layout:
  //   "kiosk": {
  //     "auto_login_enabled": true  //
  //   }
  static const char kKioskDictionaryName[];
  static const char kKeyAutoLoginState[];

  // Sub directory under DIR_USER_DATA to store cached icon files.
  static const char kIconCacheDir[];

  // Gets the KioskAppManager instance, which is lazily created on first call.
  static KioskAppManager* Get();

  // Initializes KioskAppManager for testing, injecting the provided overrides.
  // |overrides| can be null, in which case KioskAppManager will use default
  // behavior.
  // Must be called before Get().
  static void InitializeForTesting(Overrides* overrides);

  // Prepares for shutdown and calls CleanUp() if needed.
  static void Shutdown();

  // Registers kiosk app entries in local state.
  static void RegisterPrefs(PrefRegistrySimple* registry);

  // Removes cryptohomes which could not be removed during the previous session.
  static void RemoveObsoleteCryptohomes();

  static bool IsConsumerKioskEnabled();

  // Initiates reading of consumer kiosk mode auto-launch status.
  void GetConsumerKioskAutoLaunchStatus(
      const GetConsumerKioskAutoLaunchStatusCallback& callback);

  // Enables consumer kiosk mode app auto-launch feature. Upon completion,
  // |callback| will be invoked with outcome of this operation.
  void EnableConsumerKioskAutoLaunch(
      const EnableKioskAutoLaunchCallback& callback);

  // Returns true if this device is consumer kiosk auto launch enabled.
  bool IsConsumerKioskDeviceWithAutoLaunch();

  // Returns auto launcher app id or an empty string if there is none.
  std::string GetAutoLaunchApp() const;

  // Sets |app_id| as the app to auto launch at start up.
  void SetAutoLaunchApp(const std::string& app_id,
                        OwnerSettingsServiceChromeOS* service);

  // Returns true if there is a pending auto-launch request.
  bool IsAutoLaunchRequested() const;

  // Returns true if owner/policy enabled auto launch.
  bool IsAutoLaunchEnabled() const;

  // Enable auto launch setter.
  void SetEnableAutoLaunch(bool value);

  // Returns the cached required platform version of the auto launch with
  // zero delay kiosk app.
  std::string GetAutoLaunchAppRequiredPlatformVersion() const;

  // Adds/removes a kiosk app by id. When removed, all locally cached data
  // will be removed as well.
  void AddApp(const std::string& app_id, OwnerSettingsServiceChromeOS* service);
  void RemoveApp(const std::string& app_id,
                 OwnerSettingsServiceChromeOS* service);

  // Gets info of all apps that have no meta data load error.
  void GetApps(Apps* apps) const;

  // Gets app data for the given app id. Returns true if |app_id| is known and
  // |app| is populated. Otherwise, return false.
  bool GetApp(const std::string& app_id, App* app) const;

  // Gets whether the bailout shortcut is disabled.
  bool GetDisableBailoutShortcut() const;

  // Clears locally cached app data.
  void ClearAppData(const std::string& app_id);

  // Updates app data from the |app| in |profile|. |app| is provided to cover
  // the case of app update case where |app| is the new version and is not
  // finished installing (e.g. because old version is still running). Otherwise,
  // |app| could be NULL and the current installed app in |profile| will be
  // used.
  void UpdateAppDataFromProfile(const std::string& app_id,
                                Profile* profile,
                                const extensions::Extension* app);

  void RetryFailedAppDataFetch();

  // Returns true if the app is found in cache.
  bool HasCachedCrx(const std::string& app_id) const;

  // Gets the path and version of the cached crx with |app_id|.
  // Returns true if the app is found in cache.
  bool GetCachedCrx(const std::string& app_id,
                    base::FilePath* file_path,
                    std::string* version) const;

  void AddObserver(KioskAppManagerObserver* observer);
  void RemoveObserver(KioskAppManagerObserver* observer);

  // Initialized or updates the app whose prefs are available to primary kiosk
  // app external extensions loader.
  void UpdatePrimaryAppLoaderPrefs(const std::string& id);

  // Returns the primary app prefs that can be used by external extensions
  // loader - this will return null until |UpdatePrimaryAppLoaderPrefs| is
  // called.
  std::unique_ptr<base::DictionaryValue> GetPrimaryAppLoaderPrefs();

  // Registers a callback called whenever the available primary app external
  // extension prefs get updated (i.e. when UpdatePrimaryAppLoaderPrefs() is
  // called).
  void SetPrimaryAppLoaderPrefsChangedHandler(base::RepeatingClosure handler);

  // Initialized or updates the apps whose prefs are available to secondary
  // kiosk apps external extensions loader.
  void UpdateSecondaryAppsLoaderPrefs(const std::vector<std::string>& ids);

  // Returns the secondary apps prefs that can be used by external extensions
  // loader - this will return null until |UpdateSecondaryAppsLoaderPrefs| is
  // called.
  std::unique_ptr<base::DictionaryValue> GetSecondaryAppsLoaderPrefs();

  // Registers a callback called whenever the available secondary apps external
  // extension prefs get updated (i.e. when UpdateSecondayAppsLoaderPrefs() is
  // called).
  void SetSecondaryAppsLoaderPrefsChangedHandler(
      base::RepeatingClosure handler);

  void UpdateExternalCache();

  // Monitors kiosk external update from usb stick.
  void MonitorKioskExternalUpdate();

  // Invoked when kiosk app cache has been updated.
  void OnKioskAppCacheUpdated(const std::string& app_id);

  // Invoked when kiosk app updating from usb stick has been completed.
  // |success| indicates if all the updates are completed successfully.
  void OnKioskAppExternalUpdateComplete(bool success);

  // Installs the validated external extension into cache.
  void PutValidatedExternalExtension(
      const std::string& app_id,
      const base::FilePath& crx_path,
      const std::string& version,
      ExternalCache::PutExternalExtensionCallback callback);

  // Whether the current platform is compliant with the given required
  // platform version.
  bool IsPlatformCompliant(const std::string& required_platform_version) const;

  // Whether the platform is compliant for the given app.
  bool IsPlatformCompliantWithApp(const extensions::Extension* app) const;

  // Notifies the KioskAppManager that a given app was auto-launched
  // automatically with no delay on startup. Certain privacy-sensitive
  // kiosk-mode behavior (such as network reporting) is only enabled for
  // kiosk apps that are immediately auto-launched on startup.
  void SetAppWasAutoLaunchedWithZeroDelay(const std::string& app_id);

  // Initialize |app_session_|.
  void InitSession(Profile* profile, const std::string& app_id);

  // Adds an app with the given meta data directly and skips meta data fetching
  // for test.
  void AddAppForTest(const std::string& app_id,
                     const AccountId& account_id,
                     const GURL& update_url,
                     const std::string& required_platform_version);

  AppSession* app_session() { return app_session_.get(); }

 private:
  friend struct base::LazyInstanceTraitsBase<KioskAppManager>;
  friend std::default_delete<KioskAppManager>;
  friend class KioskAppManagerTest;
  friend class KioskTest;
  friend class KioskUpdateTest;

  enum AutoLoginState {
    AUTOLOGIN_NONE      = 0,
    AUTOLOGIN_REQUESTED = 1,
    AUTOLOGIN_APPROVED  = 2,
    AUTOLOGIN_REJECTED  = 3,
  };

  KioskAppManager();
  ~KioskAppManager() override;

  // Stop all data loading and remove its dependency on CrosSettings.
  void CleanUp();

  // Gets KioskAppData for the given app id.
  const KioskAppData* GetAppData(const std::string& app_id) const;
  KioskAppData* GetAppDataMutable(const std::string& app_id);

  // Updates app data |apps_| based on CrosSettings.
  void UpdateAppData();

  // Clear cached data and crx of the removed apps.
  void ClearRemovedApps(
      const std::map<std::string, std::unique_ptr<KioskAppData>>& old_apps);

  // Updates the prefs of |external_cache_| from |apps_|.
  void UpdateExternalCachePrefs();

  // KioskAppDataDelegate overrides:
  void GetKioskAppIconCacheDir(base::FilePath* cache_dir) override;
  void OnKioskAppDataChanged(const std::string& app_id) override;
  void OnKioskAppDataLoadFailure(const std::string& app_id) override;

  // ExternalCacheDelegate:
  void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override;
  void OnExtensionLoadedInCache(const std::string& id) override;
  void OnExtensionDownloadFailed(const std::string& id) override;
  std::string GetInstalledExtensionVersion(const std::string& id) override;

  // Callback for InstallAttributes::LockDevice() during
  // EnableConsumerModeKiosk() call.
  void OnLockDevice(const EnableKioskAutoLaunchCallback& callback,
                    InstallAttributes::LockResult result);

  // Callback for InstallAttributes::ReadImmutableAttributes() during
  // GetConsumerKioskModeStatus() call.
  void OnReadImmutableAttributes(
      const GetConsumerKioskAutoLaunchStatusCallback& callback);

  // Callback for reading handling checks of the owner public.
  void OnOwnerFileChecked(
      const GetConsumerKioskAutoLaunchStatusCallback& callback,
      bool* owner_present);

  // Reads/writes auto login state from/to local state.
  AutoLoginState GetAutoLoginState() const;
  void SetAutoLoginState(AutoLoginState state);

  // Returns the auto launch delay.
  base::TimeDelta GetAutoLaunchDelay() const;

  // Gets list of user switches that should be passed to Chrome in case current
  // session has to be restored, e.g. in case of a crash. The switches will be
  // returned as |switches| command line arguments.
  // Returns whether the set of switches would have to be changed in respect to
  // the current set of switches - if that is not the case |switches| might not
  // get populated.
  bool GetSwitchesForSessionRestore(const std::string& app_id,
                                    base::CommandLine* switches);

  // True if machine ownership is already established.
  bool ownership_established_ = false;
  std::vector<std::unique_ptr<KioskAppData>> apps_;
  std::string auto_launch_app_id_;
  std::string currently_auto_launched_with_zero_delay_app_;
  base::ObserverList<KioskAppManagerObserver, true>::Unchecked observers_;

  std::unique_ptr<CrosSettings::ObserverSubscription>
      local_accounts_subscription_;
  std::unique_ptr<CrosSettings::ObserverSubscription>
      local_account_auto_login_id_subscription_;

  std::unique_ptr<ExternalCache> external_cache_;

  std::unique_ptr<KioskExternalUpdater> usb_stick_updater_;

  // Last app id set by UpdatePrimaryAppLoaderPrefs().
  base::Optional<std::string> primary_app_id_;

  // Callback registered using SetPrimaryAppLoaderPrefsChangedHandler().
  base::RepeatingClosure primary_app_changed_handler_;

  // Extensions id set by UpdateSecondatyAppsLoaderPrefs().
  base::Optional<std::vector<std::string>> secondary_app_ids_;

  // Callback registered using SetSecondaryAppsLoaderPrefsChangedHandler().
  base::RepeatingClosure secondary_apps_changed_handler_;

  std::unique_ptr<AppSession> app_session_;

  DISALLOW_COPY_AND_ASSIGN(KioskAppManager);
};

}  // namespace chromeos

#endif  // CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_MANAGER_H_
