// Copyright 2016 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_NOTE_TAKING_HELPER_H_
#define CHROME_BROWSER_CHROMEOS_NOTE_TAKING_HELPER_H_

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observer.h"
#include "chrome/browser/chromeos/arc/arc_session_manager.h"
#include "components/arc/common/intent_helper.mojom.h"
#include "components/arc/intent_helper/arc_intent_helper_observer.h"
#include "components/prefs/pref_change_registrar.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/extension.h"

class Profile;

namespace base {
class FilePath;
}  // namespace base

namespace content {
class BrowserContext;
}  // namespace content

namespace extensions {
class Extension;
class ExtensionRegistry;
namespace api {
namespace app_runtime {
struct ActionData;
}  // namespace app_runtime
}  // namespace api
}  // namespace extensions

namespace chromeos {

class NoteTakingControllerClient;

// Describes an app's level of support for lock screen enabled note taking.
// IMPORTANT: These constants are used in settings UI, so be careful about
//     reordering/adding/removing items.
enum class NoteTakingLockScreenSupport {
  // The app does not support note taking on lock screen.
  kNotSupported = 0,
  // The app supports lock screen note taking, but is not allowed to run on the
  // lock screen due to policy settings.
  kNotAllowedByPolicy = 1,
  // The app supports note taking on lock screen, but is not enabled as a
  // lock screen note taking app by the user. This state implies that the user
  // can be offered to enable this app as the lock screen note taking handler.
  kSupported = 2,
  // The app is enabled by the user to run as a note taking handler on the lock
  // screen. Note that, while more than one app can be in enabled state at a
  // same time, currently only the preferred note taking app will be launchable
  // from the lock screen UI.
  kEnabled = 3,
};

// Information about an installed note-taking app.
struct NoteTakingAppInfo {
  // Application name to display to user.
  std::string name;

  // Either an extension ID (in the case of a Chrome app) or a package name (in
  // the case of an Android app).
  std::string app_id;

  // True if this is the preferred note-taking app.
  bool preferred;

  // Whether the app supports taking notes on Chrome OS lock screen. Note that
  // this ability is guarded by enable-lock-screen-apps feature flag, and
  // whitelisted to Keep apps.
  NoteTakingLockScreenSupport lock_screen_support;
};

using NoteTakingAppInfos = std::vector<NoteTakingAppInfo>;

// Singleton class used to launch a note-taking app.
class NoteTakingHelper : public arc::ArcIntentHelperObserver,
                         public arc::ArcSessionManager::Observer,
                         public content::NotificationObserver,
                         public extensions::ExtensionRegistryObserver {
 public:
  // Interface for observing changes to the list of available apps.
  class Observer {
   public:
    virtual ~Observer() = default;

    // Called when the list of available apps that will be returned by
    // GetAvailableApps() changes or when |play_store_enabled_| changes state.
    virtual void OnAvailableNoteTakingAppsUpdated() = 0;

    // Called when the preferred note taking app (or its properties) in
    // |profile| is updated.
    virtual void OnPreferredNoteTakingAppUpdated(Profile* profile) = 0;
  };

  // Describes the result of an attempt to launch a note-taking app. Values must
  // not be renumbered, as this is used by histogram metrics.
  enum class LaunchResult {
    // A Chrome app was launched successfully.
    CHROME_SUCCESS = 0,
    // The requested Chrome app was unavailable.
    CHROME_APP_MISSING = 1,
    // An Android app was launched successfully.
    ANDROID_SUCCESS = 2,
    // An Android app couldn't be launched due to the profile not being allowed
    // to use ARC.
    ANDROID_NOT_SUPPORTED_BY_PROFILE = 3,
    // An Android app couldn't be launched due to ARC not running.
    ANDROID_NOT_RUNNING = 4,
    // An Android app couldn't be launched due to a failure to convert the
    // supplied path to an ARC URL.
    ANDROID_FAILED_TO_CONVERT_PATH = 5,
    // No attempt was made due to a preferred app not being specified.
    NO_APP_SPECIFIED = 6,
    // No Android or Chrome apps were available.
    NO_APPS_AVAILABLE = 7,
    // This value must remain last and should be incremented when a new reason
    // is inserted.
    MAX = 8,
  };

  // Callback used to launch a Chrome app.
  using LaunchChromeAppCallback = base::Callback<void(
      content::BrowserContext* context,
      const extensions::Extension*,
      std::unique_ptr<extensions::api::app_runtime::ActionData>,
      const base::FilePath&)>;

  // Intent action used to launch Android apps.
  static const char kIntentAction[];

  // Extension IDs for the development and released versions of the Google Keep
  // Chrome app.
  static const char kDevKeepExtensionId[];
  static const char kProdKeepExtensionId[];

  // Names of histograms.
  static const char kPreferredLaunchResultHistogramName[];
  static const char kDefaultLaunchResultHistogramName[];

  static void Initialize();
  static void Shutdown();
  static NoteTakingHelper* Get();

  bool play_store_enabled() const { return play_store_enabled_; }
  bool android_apps_received() const { return android_apps_received_; }

  void set_launch_chrome_app_callback_for_test(
      const LaunchChromeAppCallback& callback) {
    launch_chrome_app_callback_ = callback;
  }

  // Adds or removes an observer.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Returns a list of available note-taking apps.
  std::vector<NoteTakingAppInfo> GetAvailableApps(Profile* profile);

  // Returns the preferred app info, if the preferred app exists and is a Chrome
  // app.
  std::unique_ptr<NoteTakingAppInfo> GetPreferredChromeAppInfo(
      Profile* profile);

  // Sets the preferred note-taking app. |app_id| is a value from a
  // NoteTakingAppInfo object.
  void SetPreferredApp(Profile* profile, const std::string& app_id);

  // Enables or disables preferred note taking apps from running on the lock
  // screen.
  // Returns whether the app status changed.
  bool SetPreferredAppEnabledOnLockScreen(Profile* profile, bool enabled);

  // Returns true if an app that can be used to take notes is available. UI
  // surfaces that call LaunchAppForNewNote() should be hidden otherwise.
  bool IsAppAvailable(Profile* profile);

  // Launches the note-taking app to create a new note, optionally additionally
  // passing a file (|path| may be empty). IsAppAvailable() must be called
  // first.
  void LaunchAppForNewNote(Profile* profile, const base::FilePath& path);

  // arc::ArcIntentHelperObserver:
  void OnIntentFiltersUpdated() override;

  // arc::ArcSessionManager::Observer:
  void OnArcPlayStoreEnabledChanged(bool enabled) override;

  // Sets the profile which supports note taking apps on the lock screen.
  void SetProfileWithEnabledLockScreenApps(Profile* profile);

  NoteTakingControllerClient* GetNoteTakingControllerClientForTesting() {
    return note_taking_controller_client_.get();
  }

 private:
  // The state of app ID whitelist cache (used for determining the state of
  // note-taking apps whtielisted for the lock screen).
  enum class AppWhitelistState {
    // The whitelist value has not yet been determined.
    kUndetermined,
    // The app ID whitelist does not exist in the profile.
    kNoAppWhitelist,
    // The app ID whitelist exists in the profile.
    kAppsWhitelisted
  };

  NoteTakingHelper();
  ~NoteTakingHelper() override;

  // Returns true if |extension| is a whitelisted note-taking app and false
  // otherwise.
  bool IsWhitelistedChromeApp(const extensions::Extension* extension) const;

  // Queries and returns all installed and enabled whitelisted Chrome
  // note-taking apps for |profile|.
  std::vector<const extensions::Extension*> GetChromeApps(
      Profile* profile) const;

  // Requests a list of Android note-taking apps from ARC.
  void UpdateAndroidApps();

  // Handles ARC's response to an earlier UpdateAndroidApps() call.
  void OnGotAndroidApps(std::vector<arc::mojom::IntentHandlerInfoPtr> handlers);

  // Helper method that launches |app_id| (either an Android package name or a
  // Chrome extension ID) to create a new note with an optional attached file at
  // |path|. Returns the attempt's result.
  LaunchResult LaunchAppInternal(Profile* profile,
                                 const std::string& app_id,
                                 const base::FilePath& path);

  // content::NotificationObserver:
  void Observe(int type,
               const content::NotificationSource& source,
               const content::NotificationDetails& details) override;

  // extensions::ExtensionRegistryObserver:
  void OnExtensionLoaded(content::BrowserContext* browser_context,
                         const extensions::Extension* extension) override;
  void OnExtensionUnloaded(content::BrowserContext* browser_context,
                           const extensions::Extension* extension,
                           extensions::UnloadedExtensionReason reason) override;
  void OnShutdown(extensions::ExtensionRegistry* registry) override;

  // Determines the state of the |app|'s support for lock screen note taking.
  // |profile| - The profile in which the app is installed.
  NoteTakingLockScreenSupport GetLockScreenSupportForChromeApp(
      Profile* profile,
      const extensions::Extension* app);

  // Called when kNoteTakingAppsLockScreenWhitelist pref changes for
  // |profile_with_enabled_lock_screen_apps_|.
  void OnAllowedNoteTakingAppsChanged();

  // Updates the cached whitelist of note-taking apps allowed on the lock
  // screen - it sets |lock_screen_whitelist_state_|  and
  // |lock_screen_apps_allowed_by_policy_| to values appropriate for the current
  // |profile_with_enabled_lock_screen_apps_| state.
  void UpdateLockScreenAppsWhitelistState();

  // True iff Play Store is enabled (i.e. per the checkbox on the settings
  // page). Note that ARC may not be fully started yet when this is true, but it
  // is expected to start eventually. Similarly, ARC may not be fully shut down
  // yet when this is false, but will be eventually.
  bool play_store_enabled_ = false;

  // This is set to true after |android_apps_| is updated.
  bool android_apps_received_ = false;

  // Callback used to launch Chrome apps. Can be overridden for tests.
  LaunchChromeAppCallback launch_chrome_app_callback_;

  // Extension IDs of whitelisted (but not necessarily installed) Chrome
  // note-taking apps in the order in which they're chosen if the user hasn't
  // expressed a preference.
  std::vector<extensions::ExtensionId> whitelisted_chrome_app_ids_;

  // Cached information about available Android note-taking apps.
  NoteTakingAppInfos android_apps_;

  // Tracks ExtensionRegistry observation for different profiles.
  ScopedObserver<extensions::ExtensionRegistry,
                 extensions::ExtensionRegistryObserver>
      extension_registry_observer_;

  // The profile for which lock screen apps are enabled,
  Profile* profile_with_enabled_lock_screen_apps_ = nullptr;

  // The current AppWhitelistState for lock screen note taking in
  // |profile_with_enabled_lock_screen_apps_|. If kAppsWhitelisted,
  // |lock_screen_apps_allowed_by_policy_| should contain the set of whitelisted
  // app IDs.
  AppWhitelistState lock_screen_whitelist_state_ =
      AppWhitelistState::kUndetermined;

  // If |lock_screen_whitelist_state_| is kAppsWhitelisted, contains all app
  // IDs that are allowed to handle new-note action on the lock screen. The set
  // should only be used for apps from |profile_with_enabled_lock_screen_apps_|
  // and when |lock_screen_whitelist_state_| equals kAppsWhitelisted.
  std::set<std::string> lock_screen_apps_allowed_by_policy_;

  // Tracks kNoteTakingAppsLockScreenWhitelist pref for the profile for which
  // lock screen apps are enabled.
  PrefChangeRegistrar pref_change_registrar_;

  base::ObserverList<Observer> observers_;

  content::NotificationRegistrar registrar_;

  std::unique_ptr<NoteTakingControllerClient> note_taking_controller_client_;

  base::WeakPtrFactory<NoteTakingHelper> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(NoteTakingHelper);
};

}  // namespace chromeos

#endif  // CHROME_BROWSER_CHROMEOS_NOTE_TAKING_HELPER_H_
