// Copyright (c) 2012 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 COMPONENTS_PREFS_PREF_VALUE_STORE_H_
#define COMPONENTS_PREFS_PREF_VALUE_STORE_H_

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

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/values.h"
#include "components/prefs/pref_store.h"
#include "components/prefs/prefs_export.h"

class PersistentPrefStore;
class PrefNotifier;
class PrefRegistry;
class PrefStore;

// The PrefValueStore manages various sources of values for Preferences
// (e.g., configuration policies, extensions, and user settings). It returns
// the value of a Preference from the source with the highest priority, and
// allows setting user-defined values for preferences that are not managed.
//
// Unless otherwise explicitly noted, all of the methods of this class must
// be called on the UI thread.
class COMPONENTS_PREFS_EXPORT PrefValueStore {
 public:
  typedef base::Callback<void(const std::string&)> PrefChangedCallback;

  // Delegate used to observe certain events in the |PrefValueStore|'s lifetime.
  class Delegate {
   public:
    virtual ~Delegate() {}

    // Called by the PrefValueStore constructor with the PrefStores passed to
    // it.
    virtual void Init(PrefStore* managed_prefs,
                      PrefStore* supervised_user_prefs,
                      PrefStore* extension_prefs,
                      PrefStore* command_line_prefs,
                      PrefStore* user_prefs,
                      PrefStore* recommended_prefs,
                      PrefStore* default_prefs,
                      PrefNotifier* pref_notifier) = 0;

    virtual void InitIncognitoUserPrefs(
        scoped_refptr<PersistentPrefStore> incognito_user_prefs_overlay,
        scoped_refptr<PersistentPrefStore> incognito_user_prefs_underlay,
        const std::vector<const char*>& overlay_pref_names) = 0;

    virtual void InitPrefRegistry(PrefRegistry* pref_registry) = 0;

    // Called whenever PrefValueStore::UpdateCommandLinePrefStore is called,
    // with the same argument.
    virtual void UpdateCommandLinePrefStore(PrefStore* command_line_prefs) = 0;
  };

  // PrefStores must be listed here in order from highest to lowest priority.
  //   MANAGED contains all managed preference values that are provided by
  //      mandatory policies (e.g. Windows Group Policy or cloud policy).
  //   SUPERVISED_USER contains preferences that are valid for supervised users.
  //   EXTENSION contains preference values set by extensions.
  //   COMMAND_LINE contains preference values set by command-line switches.
  //   USER contains all user-set preference values.
  //   RECOMMENDED contains all preferences that are provided by recommended
  //      policies.
  //   DEFAULT contains all application default preference values.
  enum PrefStoreType {
    // INVALID_STORE is not associated with an actual PrefStore but used as
    // an invalid marker, e.g. as a return value.
    INVALID_STORE = -1,
    MANAGED_STORE = 0,
    SUPERVISED_USER_STORE,
    EXTENSION_STORE,
    COMMAND_LINE_STORE,
    USER_STORE,
    RECOMMENDED_STORE,
    DEFAULT_STORE,
    PREF_STORE_TYPE_MAX = DEFAULT_STORE
  };

  // In decreasing order of precedence:
  //   |managed_prefs| contains all preferences from mandatory policies.
  //   |supervised_user_prefs| contains all preferences from supervised user
  //        settings, i.e. settings configured for a supervised user by their
  //        custodian.
  //   |extension_prefs| contains preference values set by extensions.
  //   |command_line_prefs| contains preference values set by command-line
  //        switches.
  //   |user_prefs| contains all user-set preference values.
  //   |recommended_prefs| contains all preferences from recommended policies.
  //   |default_prefs| contains application-default preference values. It must
  //        be non-null if any preferences are to be registered.
  //
  // |pref_notifier| facilitates broadcasting preference change notifications
  // to the world.
  PrefValueStore(PrefStore* managed_prefs,
                 PrefStore* supervised_user_prefs,
                 PrefStore* extension_prefs,
                 PrefStore* command_line_prefs,
                 PrefStore* user_prefs,
                 PrefStore* recommended_prefs,
                 PrefStore* default_prefs,
                 PrefNotifier* pref_notifier,
                 std::unique_ptr<Delegate> delegate = nullptr);
  virtual ~PrefValueStore();

  // Creates a clone of this PrefValueStore with PrefStores overwritten
  // by the parameters passed, if unequal NULL.
  //
  // The new PrefValueStore is passed the |delegate| in its constructor.
  std::unique_ptr<PrefValueStore> CloneAndSpecialize(
      PrefStore* managed_prefs,
      PrefStore* supervised_user_prefs,
      PrefStore* extension_prefs,
      PrefStore* command_line_prefs,
      PrefStore* user_prefs,
      PrefStore* recommended_prefs,
      PrefStore* default_prefs,
      PrefNotifier* pref_notifier,
      std::unique_ptr<Delegate> delegate = nullptr);

  // A PrefValueStore can have exactly one callback that is directly
  // notified of preferences changing in the store. This does not
  // filter through the PrefNotifier mechanism, which may not forward
  // certain changes (e.g. unregistered prefs).
  void set_callback(const PrefChangedCallback& callback);

  // Gets the value for the given preference name that has the specified value
  // type. Values stored in a PrefStore that have the matching |name| but
  // a non-matching |type| are silently skipped. Returns true if a valid value
  // was found in any of the available PrefStores. Most callers should use
  // Preference::GetValue() instead of calling this method directly.
  bool GetValue(const std::string& name,
                base::Value::Type type,
                const base::Value** out_value) const;

  // Gets the recommended value for the given preference name that has the
  // specified value type. A value stored in the recommended PrefStore that has
  // the matching |name| but a non-matching |type| is silently ignored. Returns
  // true if a valid value was found. Most callers should use
  // Preference::GetRecommendedValue() instead of calling this method directly.
  bool GetRecommendedValue(const std::string& name,
                           base::Value::Type type,
                           const base::Value** out_value) const;

  // These methods return true if a preference with the given name is in the
  // indicated pref store, even if that value is currently being overridden by
  // a higher-priority source.
  bool PrefValueInManagedStore(const std::string& name) const;
  bool PrefValueInSupervisedStore(const std::string& name) const;
  bool PrefValueInExtensionStore(const std::string& name) const;
  bool PrefValueInUserStore(const std::string& name) const;

  // These methods return true if a preference with the given name is actually
  // being controlled by the indicated pref store and not being overridden by
  // a higher-priority source.
  bool PrefValueFromExtensionStore(const std::string& name) const;
  bool PrefValueFromUserStore(const std::string& name) const;
  bool PrefValueFromRecommendedStore(const std::string& name) const;
  bool PrefValueFromDefaultStore(const std::string& name) const;

  // Check whether a Preference value is modifiable by the user, i.e. whether
  // there is no higher-priority source controlling it.
  bool PrefValueUserModifiable(const std::string& name) const;

  // Check whether a Preference value is modifiable by an extension, i.e.
  // whether there is no higher-priority source controlling it.
  bool PrefValueExtensionModifiable(const std::string& name) const;

  // Update the command line PrefStore with |command_line_prefs|.
  void UpdateCommandLinePrefStore(PrefStore* command_line_prefs);

  bool IsInitializationComplete() const;

  // Check whether a particular type of PrefStore exists.
  bool HasPrefStore(PrefStoreType type) const;

 private:
  // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors
  // the PrefStore for changes, forwarding notifications to PrefValueStore. This
  // indirection is here for the sake of disambiguating notifications from the
  // individual PrefStores.
  class PrefStoreKeeper : public PrefStore::Observer {
   public:
    PrefStoreKeeper();
    ~PrefStoreKeeper() override;

    // Takes ownership of |pref_store|.
    void Initialize(PrefValueStore* store,
                    PrefStore* pref_store,
                    PrefStoreType type);

    PrefStore* store() { return pref_store_.get(); }
    const PrefStore* store() const { return pref_store_.get(); }

   private:
    // PrefStore::Observer implementation.
    void OnPrefValueChanged(const std::string& key) override;
    void OnInitializationCompleted(bool succeeded) override;

    // PrefValueStore this keeper is part of.
    PrefValueStore* pref_value_store_;

    // The PrefStore managed by this keeper.
    scoped_refptr<PrefStore> pref_store_;

    // Type of the pref store.
    PrefStoreType type_;

    DISALLOW_COPY_AND_ASSIGN(PrefStoreKeeper);
  };

  typedef std::map<std::string, base::Value::Type> PrefTypeMap;

  // Returns true if the preference with the given name has a value in the
  // given PrefStoreType, of the same value type as the preference was
  // registered with.
  bool PrefValueInStore(const std::string& name, PrefStoreType store) const;

  // Returns true if a preference has an explicit value in any of the
  // stores in the range specified by |first_checked_store| and
  // |last_checked_store|, even if that value is currently being
  // overridden by a higher-priority store.
  bool PrefValueInStoreRange(const std::string& name,
                             PrefStoreType first_checked_store,
                             PrefStoreType last_checked_store) const;

  // Returns the pref store type identifying the source that controls the
  // Preference identified by |name|. If none of the sources has a value,
  // INVALID_STORE is returned. In practice, the default PrefStore
  // should always have a value for any registered preferencem, so INVALID_STORE
  // indicates an error.
  PrefStoreType ControllingPrefStoreForPref(const std::string& name) const;

  // Get a value from the specified |store|.
  bool GetValueFromStore(const std::string& name,
                         PrefStoreType store,
                         const base::Value** out_value) const;

  // Get a value from the specified |store| if its |type| matches.
  bool GetValueFromStoreWithType(const std::string& name,
                                 base::Value::Type type,
                                 PrefStoreType store,
                                 const base::Value** out_value) const;

  // Called upon changes in individual pref stores in order to determine whether
  // the user-visible pref value has changed. Triggers the change notification
  // if the effective value of the preference has changed, or if the store
  // controlling the pref has changed.
  void NotifyPrefChanged(const std::string& path, PrefStoreType new_store);

  // Called from the PrefStoreKeeper implementation when a pref value for |key|
  // changed in the pref store for |type|.
  void OnPrefValueChanged(PrefStoreType type, const std::string& key);

  // Handle the event that the store for |type| has completed initialization.
  void OnInitializationCompleted(PrefStoreType type, bool succeeded);

  // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take
  // ownership of the passed |pref_store|.
  void InitPrefStore(PrefStoreType type, PrefStore* pref_store);

  // Checks whether initialization is completed and tells the notifier if that
  // is the case.
  void CheckInitializationCompleted();

  // Get the PrefStore pointer for the given type. May return NULL if there is
  // no PrefStore for that type.
  PrefStore* GetPrefStore(PrefStoreType type) {
    return pref_stores_[type].store();
  }
  const PrefStore* GetPrefStore(PrefStoreType type) const {
    return pref_stores_[type].store();
  }

  // Keeps the PrefStore references in order of precedence.
  PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1];

  PrefChangedCallback pref_changed_callback_;

  // Used for generating notifications. This is a weak reference,
  // since the notifier is owned by the corresponding PrefService.
  PrefNotifier* pref_notifier_;

  // A mapping of preference names to their registered types.
  PrefTypeMap pref_types_;

  // True if not all of the PrefStores were initialized successfully.
  bool initialization_failed_;

  // Might be null.
  std::unique_ptr<Delegate> delegate_;

  DISALLOW_COPY_AND_ASSIGN(PrefValueStore);
};

namespace std {

template <>
struct hash<PrefValueStore::PrefStoreType> {
  size_t operator()(PrefValueStore::PrefStoreType type) const {
    return std::hash<
        std::underlying_type<PrefValueStore::PrefStoreType>::type>()(type);
  }
};

}  // namespace std

#endif  // COMPONENTS_PREFS_PREF_VALUE_STORE_H_
