// Copyright (c) 2012 The Chromium OS 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 POWER_MANAGER_COMMON_PREFS_H_
#define POWER_MANAGER_COMMON_PREFS_H_

#include <stdint.h>

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

#include <base/callback_forward.h>
#include <base/compiler_specific.h>
#include <base/observer_list.h>
#include <base/time/time.h>
#include <base/timer/timer.h>

namespace power_manager {

class PrefsObserver;

// Interface for reading and writing preferences.
class PrefsInterface {
 public:
  virtual ~PrefsInterface() {}

  // Adds or removes an observer.
  virtual void AddObserver(PrefsObserver* observer) = 0;
  virtual void RemoveObserver(PrefsObserver* observer) = 0;

  // Reads settings and returns true on success.
  virtual bool GetString(const std::string& name, std::string* value) = 0;
  virtual bool GetInt64(const std::string& name, int64_t* value) = 0;
  virtual bool GetDouble(const std::string& name, double* value) = 0;
  virtual bool GetBool(const std::string& name, bool* value) = 0;

  // Writes settings (possibly asynchronously, although any deferred
  // changes will be reflected in Get*() calls).
  virtual void SetString(const std::string& name, const std::string& value) = 0;
  virtual void SetInt64(const std::string& name, int64_t value) = 0;
  virtual void SetDouble(const std::string& name, double value) = 0;
};

class PrefsSourceInterface;

using PrefsSourceInterfaceVector =
    std::vector<std::unique_ptr<PrefsSourceInterface>>;

// Result of a pref file read operation.
struct PrefReadResult {
  std::string value;        // The value that was read.
  std::string source_desc;  // Where |value| came from, for logging.
};

// Interface for readable sources of preferences.
class PrefsSourceInterface {
 public:
  virtual ~PrefsSourceInterface() {}

  // Gets a description of this source suitable for logging.
  virtual std::string GetDescription() const = 0;

  // Reads a pref named |name| from this source into the given string.
  virtual bool ReadPrefString(const std::string& name,
                              std::string* value_out) = 0;
};

// Interface for readable and writable storage of preferences.
class PrefsStoreInterface : public PrefsSourceInterface {
 public:
  // Callback type for Watch(). |name| refers to the updated preference.
  using ChangeCallback = base::Callback<void(const std::string& name)>;

  // Writes a pref named |name| to this store.
  virtual bool WritePrefString(const std::string& name,
                               const std::string& value) = 0;

  // Starts watching for changes in this store and call |callback| with changes.
  // If called multiple times, only the last callback will be notified.
  // Returns true on success.
  virtual bool Watch(const ChangeCallback& callback) = 0;
};

// PrefsInterface implementation that reads and writes prefs from/to disk and
// from libcros_config.
// Multiple directories are supported; this allows a default set of prefs
// to be placed on the readonly root partition and a second set of
// prefs under /var to be overlaid and changed at runtime.
class Prefs : public PrefsInterface {
 public:
  // Helper class for tests.
  class TestApi {
   public:
    explicit TestApi(Prefs* prefs);
    ~TestApi();

    void set_write_interval(base::TimeDelta interval) {
      prefs_->write_interval_ = interval;
    }

    // Calls HandleWritePrefsTimeout().  Returns false if the timeout
    // wasn't set.
    bool TriggerWriteTimeout();

   private:
    Prefs* prefs_;  // weak

    DISALLOW_COPY_AND_ASSIGN(TestApi);
  };

  Prefs();
  ~Prefs() override;

  // Returns the default writable store of prefs, to be passed to Init().
  static std::unique_ptr<PrefsStoreInterface> GetDefaultStore();

  // Returns the default sources where prefs are stored, to be passed to Init().
  static PrefsSourceInterfaceVector GetDefaultSources();

  // Initialize the preference store and sources. The |store| takes highest
  // precedence when reading preferences, followed by the |sources|, in order.
  // The |store| is also used to write preferences and watched for changes.
  bool Init(std::unique_ptr<PrefsStoreInterface> store,
            PrefsSourceInterfaceVector sources);

  // PrefsInterface implementation:
  void AddObserver(PrefsObserver* observer) override;
  void RemoveObserver(PrefsObserver* observer) override;
  bool GetString(const std::string& name, std::string* value) override;
  bool GetInt64(const std::string& name, int64_t* value) override;
  bool GetDouble(const std::string& name, double* value) override;
  bool GetBool(const std::string& name, bool* value) override;
  void SetString(const std::string& name, const std::string& value) override;
  void SetInt64(const std::string& name, int64_t value) override;
  void SetDouble(const std::string& name, double value) override;

 private:
  // Handle changes to pref values in |pref_store_|.
  void HandlePrefChanged(const std::string& name);

  // Reads string values of pref given by |name| from all the sources in
  // |pref_sources_| in order, where they exist.  Strips them of whitespace.
  // Stores each read result in |results|.
  // If |read_all| is true, it will attempt to read from all pref paths.
  // Otherwise it will return after successfully reading one pref source.
  void GetPrefResults(const std::string& name,
                      bool read_all,
                      std::vector<PrefReadResult>* results);

  // Calls WritePrefs() immediately if prefs haven't been written to disk
  // recently.  Otherwise, schedules HandleWritePrefsTimeout() if it isn't
  // already scheduled.
  void ScheduleWrite();

  // Writes |prefs_to_write_| to |pref_store_|, updates |last_write_time_|,
  // and clears |prefs_to_write_|.
  void WritePrefs();

  // The pref store is the highest precedence source of pref values and the
  // writable sink for preferences.
  std::unique_ptr<PrefsStoreInterface> pref_store_;

  // List of pref sources to read from, in order of precedence.
  // A value read from the first path will be used instead of values from the
  // other paths.
  PrefsSourceInterfaceVector pref_sources_;

  base::ObserverList<PrefsObserver> observers_;

  // Calls WritePrefs().
  base::OneShotTimer write_prefs_timer_;

  // Last time at which WritePrefs() was called.
  base::TimeTicks last_write_time_;

  // Minimum time between prefs getting written to disk.
  base::TimeDelta write_interval_;

  // Map from name to stringified value of prefs that need to be written to
  // the first path in |pref_paths_|.
  std::map<std::string, std::string> prefs_to_write_;

  DISALLOW_COPY_AND_ASSIGN(Prefs);
};

}  // namespace power_manager

#endif  // POWER_MANAGER_COMMON_PREFS_H_
