// 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_EXTENSION_PREF_VALUE_MAP_H_
#define EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_

#include <map>
#include <memory>
#include <set>
#include <string>

#include "base/macros.h"
#include "base/observer_list.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/browser/extension_prefs_scope.h"

class PrefValueMap;

namespace base {
class Time;
class Value;
}

// Non-persistent data container that is shared by ExtensionPrefStores. All
// extension pref values (incognito and regular) are stored herein and
// provided to ExtensionPrefStores.
//
// The semantics of the ExtensionPrefValueMap are:
// - A regular setting applies to regular browsing sessions as well as incognito
//   browsing sessions.
// - An incognito setting applies only to incognito browsing sessions, not to
//   regular ones. It takes precedence over a regular setting set by the same
//   extension.
// - A regular-only setting applies only to regular browsing sessions, not to
//   incognito ones. It takes precedence over a regular setting set by the same
//   extension.
// - If two different extensions set a value for the same preference (and both
//   values apply to the regular/incognito browsing session), the extension that
//   was installed later takes precedence, regardless of whether the settings
//   are regular, incognito or regular-only.
//
// The following table illustrates the behavior:
//   A.reg | A.reg_only | A.inc | B.reg | B.reg_only | B.inc | E.reg | E.inc
//     1   |      -     |   -   |   -   |      -     |   -   |   1   |   1
//     1   |      2     |   -   |   -   |      -     |   -   |   2   |   1
//     1   |      -     |   3   |   -   |      -     |   -   |   1   |   3
//     1   |      2     |   3   |   -   |      -     |   -   |   2   |   3
//     1   |      -     |   -   |   4   |      -     |   -   |   4   |   4
//     1   |      2     |   3   |   4   |      -     |   -   |   4   |   4
//     1   |      -     |   -   |   -   |      5     |   -   |   5   |   1
//     1   |      -     |   3   |   4   |      5     |   -   |   5   |   4
//     1   |      -     |   -   |   -   |      -     |   6   |   1   |   6
//     1   |      2     |   -   |   4   |      -     |   6   |   4   |   6
//     1   |      2     |   3   |   -   |      5     |   6   |   5   |   6
//
// A = extension A, B = extension B, E = effective value
// .reg = regular value
// .reg_only = regular-only value
// .inc = incognito value
// Extension B has higher precedence than A.
class ExtensionPrefValueMap : public KeyedService {
 public:
  // Observer interface for monitoring ExtensionPrefValueMap.
  class Observer {
   public:
    // Called when the value for the given |key| set by one of the extensions
    // changes. This does not necessarily mean that the effective value has
    // changed.
    virtual void OnPrefValueChanged(const std::string& key) = 0;
    // Notification about the ExtensionPrefValueMap being fully initialized.
    virtual void OnInitializationCompleted() = 0;
    // Called when the ExtensionPrefValueMap is being destroyed. When called,
    // observers must unsubscribe.
    virtual void OnExtensionPrefValueMapDestruction() = 0;

   protected:
    virtual ~Observer() {}
  };

  ExtensionPrefValueMap();
  ~ExtensionPrefValueMap() override;

  // KeyedService implementation.
  void Shutdown() override;

  // Set an extension preference |value| for |key| of extension |ext_id|.
  // Takes ownership of |value|.
  // Note that regular extension pref values need to be reported to
  // incognito and to regular ExtensionPrefStores.
  // Precondition: the extension must be registered.
  void SetExtensionPref(const std::string& ext_id,
                        const std::string& key,
                        extensions::ExtensionPrefsScope scope,
                        base::Value* value);

  // Remove the extension preference value for |key| of extension |ext_id|.
  // Precondition: the extension must be registered.
  void RemoveExtensionPref(const std::string& ext_id,
                           const std::string& key,
                           extensions::ExtensionPrefsScope scope);

  // Returns true if currently no extension with higher precedence controls the
  // preference. If |incognito| is true and the extension does not have
  // incognito permission, CanExtensionControlPref returns false.
  // Note that this function does does not consider the existence of
  // policies. An extension is only really able to control a preference if
  // PrefService::Preference::IsExtensionModifiable() returns true as well.
  bool CanExtensionControlPref(const std::string& extension_id,
                               const std::string& pref_key,
                               bool incognito) const;

  // Removes all "incognito session only" preference values.
  void ClearAllIncognitoSessionOnlyPreferences();

  // Returns true if an extension identified by |extension_id| controls the
  // preference. This means this extension has set a preference value and no
  // other extension with higher precedence overrides it. If |from_incognito|
  // is not NULL, looks at incognito preferences first, and |from_incognito| is
  // set to true if the effective pref value is coming from the incognito
  // preferences, false if it is coming from the normal ones.
  // Note that the this function does does not consider the existence of
  // policies. An extension is only really able to control a preference if
  // PrefService::Preference::IsExtensionModifiable() returns true as well.
  bool DoesExtensionControlPref(const std::string& extension_id,
                                const std::string& pref_key,
                                bool* from_incognito) const;

  // Returns the ID of the extension that currently controls this preference
  // for a regular profile. Incognito settings are ignored.
  // Returns an empty string if this preference is not controlled by an
  // extension.
  std::string GetExtensionControllingPref(const std::string& pref_key) const;

  // Tell the store it's now fully initialized.
  void NotifyInitializationCompleted();

  // Registers the time when an extension |ext_id| is installed.
  void RegisterExtension(const std::string& ext_id,
                         const base::Time& install_time,
                         bool is_enabled,
                         bool is_incognito_enabled);

  // Deletes all entries related to extension |ext_id|.
  void UnregisterExtension(const std::string& ext_id);

  // Hides or makes the extension preference values of the specified extension
  // visible.
  void SetExtensionState(const std::string& ext_id, bool is_enabled);

  // Sets whether the extension has permission to access incognito state.
  void SetExtensionIncognitoState(const std::string& ext_id,
                                  bool is_incognito_enabled);

  // Adds an observer and notifies it about the currently stored keys.
  void AddObserver(Observer* observer);

  void RemoveObserver(Observer* observer);

  const base::Value* GetEffectivePrefValue(const std::string& key,
                                           bool incognito,
                                           bool* from_incognito) const;

 private:
  struct ExtensionEntry;

  typedef std::map<std::string, std::unique_ptr<ExtensionEntry>>
      ExtensionEntryMap;

  const PrefValueMap* GetExtensionPrefValueMap(
      const std::string& ext_id,
      extensions::ExtensionPrefsScope scope) const;

  PrefValueMap* GetExtensionPrefValueMap(
      const std::string& ext_id,
      extensions::ExtensionPrefsScope scope);

  // Returns all keys of pref values that are set by the extension of |entry|,
  // regardless whether they are set for incognito or regular pref values.
  void GetExtensionControlledKeys(const ExtensionEntry& entry,
                                  std::set<std::string>* out) const;

  // Returns an iterator to the extension which controls the preference |key|.
  // If |incognito| is true, looks at incognito preferences first. In that case,
  // if |from_incognito| is not NULL, it is set to true if the effective pref
  // value is coming from the incognito preferences, false if it is coming from
  // the normal ones.
  ExtensionEntryMap::const_iterator GetEffectivePrefValueController(
      const std::string& key,
      bool incognito,
      bool* from_incognito) const;

  void NotifyOfDestruction();
  void NotifyPrefValueChanged(const std::string& key);
  void NotifyPrefValueChanged(const std::set<std::string>& keys);

  // Mapping of which extension set which preference value. The effective
  // preferences values (i.e. the ones with the highest precedence)
  // are stored in ExtensionPrefStores.
  ExtensionEntryMap entries_;

  // In normal Profile shutdown, Shutdown() notifies observers that we are
  // being destroyed. In tests, it isn't called, so the notification must
  // be done in the destructor. This bit tracks whether it has been done yet.
  bool destroyed_;

  base::ObserverList<Observer, true>::Unchecked observers_;

  DISALLOW_COPY_AND_ASSIGN(ExtensionPrefValueMap);
};

#endif  // EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_
