// 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(const TestApi&) = delete;
    TestApi& operator=(const TestApi&) = delete;

    ~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

  };

  Prefs();
  Prefs(const Prefs&) = delete;
  Prefs& operator=(const Prefs&) = delete;

  ~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_;
};

}  // namespace power_manager

#endif  // POWER_MANAGER_COMMON_PREFS_H_
