// Copyright 2016 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_UPDATE_CLIENT_PERSISTED_DATA_H_
#define COMPONENTS_UPDATE_CLIENT_PERSISTED_DATA_H_

#include <string>
#include <vector>

#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/values.h"

class PrefRegistrySimple;
class PrefService;

namespace update_client {

class ActivityDataService;

// A PersistedData is a wrapper layer around a PrefService, designed to maintain
// update data that outlives the browser process and isn't exposed outside of
// update_client.
//
// The public methods of this class should be called only on the thread that
// initializes it - which also has to match the thread the PrefService has been
// initialized on.
class PersistedData {
 public:
  // Constructs a provider using the specified |pref_service| and
  // |activity_data_service|.
  // The associated preferences are assumed to already be registered.
  // The |pref_service| and |activity_data_service| must outlive the entire
  // update_client.
  PersistedData(PrefService* pref_service,
                ActivityDataService* activity_data_service);

  ~PersistedData();

  // Returns the DateLastRollCall (the server-localized calendar date number the
  // |id| was last checked by this client on) for the specified |id|.
  // -2 indicates that there is no recorded date number for the |id|.
  int GetDateLastRollCall(const std::string& id) const;

  // Returns the DateLastActive (the server-localized calendar date number the
  // |id| was last active by this client on) for the specified |id|.
  // -1 indicates that there is no recorded date for the |id| (i.e. this is the
  // first time the |id| is active).
  // -2 indicates that the |id| has an unknown value of last active date.
  int GetDateLastActive(const std::string& id) const;

#if defined(STARBOARD)
  // Returns the version of the update that was last successfully installed for
  // the specified |id|. "" indicates that there is no recorded version value
  // for the |id|.
  std::string GetLastInstalledVersion(const std::string& id) const;

  // Returns the updater channel that is set for the specified |id|. ""
  // indicates that there is no recorded updater channel value for the |id|.
  std::string GetUpdaterChannel(const std::string& id) const;

  // Returns the updater channel for the previous app startup.
  std::string GetLatestChannel() const;
#endif

  // Returns the PingFreshness (a random token that is written into the profile
  // data whenever the DateLastRollCall it is modified) for the specified |id|.
  // "" indicates that there is no recorded freshness value for the |id|.
  std::string GetPingFreshness(const std::string& id) const;

  // Records the DateLastRollCall for the specified |ids|. |datenum| must be a
  // non-negative integer: calls with a negative |datenum| are simply ignored.
  // Calls to SetDateLastRollCall that occur prior to the persisted data store
  // has been fully initialized are ignored. Also sets the PingFreshness.
  void SetDateLastRollCall(const std::vector<std::string>& ids, int datenum);

  // Records the DateLastActive for the specified |ids|. |datenum| must be a
  // non-negative integer: calls with a negative |datenum| are simply ignored.
  // Calls to SetDateLastActive that occur prior to the persisted data store
  // has been fully initialized or the active bit of the |ids| are not set
  // are ignored.
  // This function also clears the active bits of the specified |ids| if they
  // are set.
  void SetDateLastActive(const std::vector<std::string>& ids, int datenum);

#if defined(STARBOARD)
  // Records the version of the update that is successfully installed for
  // the specified |id|.
  void SetLastInstalledVersion(const std::string& id,
                              const std::string& version);

  // Records the updater channel that is set for the specified |id|.
  void SetUpdaterChannel(const std::string& id, const std::string& channel);

  // Records the latest channel the app is on.
  void SetLatestChannel(const std::string& channel);
#endif

  // This is called only via update_client's RegisterUpdateClientPreferences.
  static void RegisterPrefs(PrefRegistrySimple* registry);

  // These functions return cohort data for the specified |id|. "Cohort"
  // indicates the membership of the client in any release channels components
  // have set up in a machine-readable format, while "CohortName" does so in a
  // human-readable form. "CohortHint" indicates the client's channel selection
  // preference.
  std::string GetCohort(const std::string& id) const;
  std::string GetCohortHint(const std::string& id) const;
  std::string GetCohortName(const std::string& id) const;

  // These functions set cohort data for the specified |id|.
  void SetCohort(const std::string& id, const std::string& cohort);
  void SetCohortHint(const std::string& id, const std::string& cohort_hint);
  void SetCohortName(const std::string& id, const std::string& cohort_name);

  // Returns true if the active bit of the specified |id| is set.
  bool GetActiveBit(const std::string& id) const;

  // The following two functions returns the number of days since the last
  // time the client checked for update/was active.
  // -1 indicates that this is the first time the client reports
  // an update check/active for the specified |id|.
  // -2 indicates that the client has no information about the
  // update check/last active of the specified |id|.
  int GetDaysSinceLastRollCall(const std::string& id) const;
  int GetDaysSinceLastActive(const std::string& id) const;

 private:
  int GetInt(const std::string& id, const std::string& key, int fallback) const;
  std::string GetString(const std::string& id, const std::string& key) const;
  void SetString(const std::string& id,
                 const std::string& key,
                 const std::string& value);

  SEQUENCE_CHECKER(sequence_checker_);
  PrefService* pref_service_;
  ActivityDataService* activity_data_service_;

  DISALLOW_COPY_AND_ASSIGN(PersistedData);
};

}  // namespace update_client

#endif  // COMPONENTS_UPDATE_CLIENT_PERSISTED_DATA_H_
