// 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.
//
// A helper class that stays in sync with a preference (bool, int, real,
// string or filepath).  For example:
//
// class MyClass {
//  public:
//   MyClass(PrefService* prefs) {
//     my_string_.Init(prefs::kHomePage, prefs);
//   }
//  private:
//   StringPrefMember my_string_;
// };
//
// my_string_ should stay in sync with the prefs::kHomePage pref and will
// update if either the pref changes or if my_string_.SetValue is called.
//
// An optional observer can be passed into the Init method which can be used to
// notify MyClass of changes. Note that if you use SetValue(), the observer
// will not be notified.

#ifndef BASE_PREFS_PREF_MEMBER_H_
#define BASE_PREFS_PREF_MEMBER_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/prefs/base_prefs_export.h"
#include "base/prefs/pref_observer.h"
#include "base/single_thread_task_runner.h"
#include "base/values.h"

class PrefService;

namespace subtle {

class BASE_PREFS_EXPORT PrefMemberBase : public PrefObserver {
 public:
  // Type of callback you can register if you need to know the name of
  // the pref that is changing.
  typedef base::Callback<void(const std::string&)> NamedChangeCallback;

  PrefService* prefs() { return prefs_; }
  const PrefService* prefs() const { return prefs_; }

 protected:
  class BASE_PREFS_EXPORT Internal
      : public base::RefCountedThreadSafe<Internal> {
   public:
    Internal();

    // Update the value, either by calling |UpdateValueInternal| directly
    // or by dispatching to the right thread.
    // Takes ownership of |value|.
    void UpdateValue(base::Value* value,
                     bool is_managed,
                     bool is_user_modifiable,
                     const base::Closure& callback) const;

    void MoveToThread(
        const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);

    // See PrefMember<> for description.
    bool IsManaged() const {
      return is_managed_;
    }

    bool IsUserModifiable() const {
      return is_user_modifiable_;
    }

   protected:
    friend class base::RefCountedThreadSafe<Internal>;
    virtual ~Internal();

    void CheckOnCorrectThread() const {
      DCHECK(IsOnCorrectThread());
    }

   private:
    // This method actually updates the value. It should only be called from
    // the thread the PrefMember is on.
    virtual bool UpdateValueInternal(const base::Value& value) const = 0;

    bool IsOnCorrectThread() const;

    scoped_refptr<base::SingleThreadTaskRunner> thread_loop_;
    mutable bool is_managed_;
    mutable bool is_user_modifiable_;

    DISALLOW_COPY_AND_ASSIGN(Internal);
  };

  PrefMemberBase();
  virtual ~PrefMemberBase();

  // See PrefMember<> for description.
  void Init(const char* pref_name, PrefService* prefs,
            const NamedChangeCallback& observer);
  void Init(const char* pref_name, PrefService* prefs);

  virtual void CreateInternal() const = 0;

  // See PrefMember<> for description.
  void Destroy();

  void MoveToThread(
      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);

  // PrefObserver
  void OnPreferenceChanged(PrefService* service,
                           const std::string& pref_name) override;

  void VerifyValuePrefName() const {
    DCHECK(!pref_name_.empty());
  }

  // This method is used to do the actual sync with the preference.
  // Note: it is logically const, because it doesn't modify the state
  // seen by the outside world. It is just doing a lazy load behind the scenes.
  void UpdateValueFromPref(const base::Closure& callback) const;

  // Verifies the preference name, and lazily loads the preference value if
  // it hasn't been loaded yet.
  void VerifyPref() const;

  const std::string& pref_name() const { return pref_name_; }

  virtual Internal* internal() const = 0;

  // Used to allow registering plain base::Closure callbacks.
  static void InvokeUnnamedCallback(const base::Closure& callback,
                                    const std::string& pref_name);

 private:
  // Ordered the members to compact the class instance.
  std::string pref_name_;
  NamedChangeCallback observer_;
  PrefService* prefs_;

 protected:
  bool setting_value_;
};

// This function implements StringListPrefMember::UpdateValue().
// It is exposed here for testing purposes.
bool BASE_PREFS_EXPORT PrefMemberVectorStringUpdate(
    const base::Value& value,
    std::vector<std::string>* string_vector);

}  // namespace subtle

template <typename ValueType>
class PrefMember : public subtle::PrefMemberBase {
 public:
  // Defer initialization to an Init method so it's easy to make this class be
  // a member variable.
  PrefMember() {}
  virtual ~PrefMember() {}

  // Do the actual initialization of the class.  Use the two-parameter
  // version if you don't want any notifications of changes.  This
  // method should only be called on the UI thread.
  void Init(const char* pref_name, PrefService* prefs,
            const NamedChangeCallback& observer) {
    subtle::PrefMemberBase::Init(pref_name, prefs, observer);
  }
  void Init(const char* pref_name, PrefService* prefs,
            const base::Closure& observer) {
    subtle::PrefMemberBase::Init(
        pref_name, prefs,
        base::Bind(&PrefMemberBase::InvokeUnnamedCallback, observer));
  }
  void Init(const char* pref_name, PrefService* prefs) {
    subtle::PrefMemberBase::Init(pref_name, prefs);
  }

  // Unsubscribes the PrefMember from the PrefService. After calling this
  // function, the PrefMember may not be used any more on the UI thread.
  // Assuming |MoveToThread| was previously called, |GetValue|, |IsManaged|,
  // and |IsUserModifiable| can still be called from the other thread but
  // the results will no longer update from the PrefService.
  // This method should only be called on the UI thread.
  void Destroy() {
    subtle::PrefMemberBase::Destroy();
  }

  // Moves the PrefMember to another thread, allowing read accesses from there.
  // Changes from the PrefService will be propagated asynchronously
  // via PostTask.
  // This method should only be used from the thread the PrefMember is currently
  // on, which is the UI thread by default.
  void MoveToThread(
      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
    subtle::PrefMemberBase::MoveToThread(task_runner);
  }

  // Check whether the pref is managed, i.e. controlled externally through
  // enterprise configuration management (e.g. windows group policy). Returns
  // false for unknown prefs.
  // This method should only be used from the thread the PrefMember is currently
  // on, which is the UI thread unless changed by |MoveToThread|.
  bool IsManaged() const {
    VerifyPref();
    return internal_->IsManaged();
  }

  // Checks whether the pref can be modified by the user. This returns false
  // when the pref is managed by a policy or an extension, and when a command
  // line flag overrides the pref.
  // This method should only be used from the thread the PrefMember is currently
  // on, which is the UI thread unless changed by |MoveToThread|.
  bool IsUserModifiable() const {
    VerifyPref();
    return internal_->IsUserModifiable();
  }

  // Retrieve the value of the member variable.
  // This method should only be used from the thread the PrefMember is currently
  // on, which is the UI thread unless changed by |MoveToThread|.
  ValueType GetValue() const {
    VerifyPref();
    return internal_->value();
  }

  // Provided as a convenience.
  ValueType operator*() const {
    return GetValue();
  }

  // Set the value of the member variable.
  // This method should only be called on the UI thread.
  void SetValue(const ValueType& value) {
    VerifyValuePrefName();
    setting_value_ = true;
    UpdatePref(value);
    setting_value_ = false;
  }

  // Returns the pref name.
  const std::string& GetPrefName() const {
    return pref_name();
  }

 private:
  class Internal : public subtle::PrefMemberBase::Internal {
   public:
    Internal() : value_(ValueType()) {}

    ValueType value() {
      CheckOnCorrectThread();
      return value_;
    }

   protected:
    virtual ~Internal() {}

    virtual BASE_PREFS_EXPORT bool UpdateValueInternal(
        const base::Value& value) const override;

    // We cache the value of the pref so we don't have to keep walking the pref
    // tree.
    mutable ValueType value_;

    DISALLOW_COPY_AND_ASSIGN(Internal);
  };

  virtual Internal* internal() const override { return internal_.get(); }
  virtual void CreateInternal() const override { internal_ = new Internal(); }

  // This method is used to do the actual sync with pref of the specified type.
  void BASE_PREFS_EXPORT UpdatePref(const ValueType& value);

  mutable scoped_refptr<Internal> internal_;

  DISALLOW_COPY_AND_ASSIGN(PrefMember);
};

// Declaration of template specialization need to be repeated here
// specifically for each specialization (rather than just once above)
// or at least one of our compilers won't be happy in all cases.
// Specifically, it was failing on ChromeOS with a complaint about
// PrefMember<FilePath>::UpdateValueInternal not being defined when
// built in a chroot with the following parameters:
//
// FEATURES="noclean nostrip" USE="-chrome_debug -chrome_remoting
// -chrome_internal -chrome_pdf component_build"
// ~/trunk/goma/goma-wrapper cros_chrome_make --board=${BOARD}
// --install --runhooks

template <>
BASE_PREFS_EXPORT void PrefMember<bool>::UpdatePref(const bool& value);

template <>
BASE_PREFS_EXPORT bool PrefMember<bool>::Internal::UpdateValueInternal(
    const base::Value& value) const;

template <>
BASE_PREFS_EXPORT void PrefMember<int>::UpdatePref(const int& value);

template <>
BASE_PREFS_EXPORT bool PrefMember<int>::Internal::UpdateValueInternal(
    const base::Value& value) const;

template <>
BASE_PREFS_EXPORT void PrefMember<double>::UpdatePref(const double& value);

template <>
BASE_PREFS_EXPORT bool PrefMember<double>::Internal::UpdateValueInternal(
    const base::Value& value) const;

template <>
BASE_PREFS_EXPORT void PrefMember<std::string>::UpdatePref(
    const std::string& value);

template <>
BASE_PREFS_EXPORT bool PrefMember<std::string>::Internal::UpdateValueInternal(
    const base::Value& value) const;

template <>
BASE_PREFS_EXPORT void PrefMember<base::FilePath>::UpdatePref(
    const base::FilePath& value);

template <>
BASE_PREFS_EXPORT bool
PrefMember<base::FilePath>::Internal::UpdateValueInternal(
    const base::Value& value) const;

template <>
BASE_PREFS_EXPORT void PrefMember<std::vector<std::string> >::UpdatePref(
    const std::vector<std::string>& value);

template <>
BASE_PREFS_EXPORT bool
PrefMember<std::vector<std::string> >::Internal::UpdateValueInternal(
    const base::Value& value) const;

typedef PrefMember<bool> BooleanPrefMember;
typedef PrefMember<int> IntegerPrefMember;
typedef PrefMember<double> DoublePrefMember;
typedef PrefMember<std::string> StringPrefMember;
typedef PrefMember<base::FilePath> FilePathPrefMember;
// This preference member is expensive for large string arrays.
typedef PrefMember<std::vector<std::string> > StringListPrefMember;

#endif  // BASE_PREFS_PREF_MEMBER_H_
