// 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 CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H__
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H__

#include <string>

#include <base/basictypes.h>
#include <base/time.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

// This gathers local system information and prepares info used by the
// Omaha request action.

namespace chromeos_update_engine {

// The default "official" Omaha update URL.
extern const char* const kProductionOmahaUrl;

class SystemState;

// This class encapsulates the data Omaha gets for the request, along with
// essential state needed for the processing of the request/response.  The
// strings in this struct should not be XML escaped.
//
// TODO (jaysri): chromium-os:39752 tracks the need to rename this class to
// reflect its lifetime more appropriately.
class OmahaRequestParams {
 public:
  OmahaRequestParams(SystemState* system_state)
      : system_state_(system_state),
        os_platform_(kOsPlatform),
        os_version_(kOsVersion),
        board_app_id_(kAppId),
        canary_app_id_(kAppId),
        delta_okay_(true),
        interactive_(false),
        update_disabled_(false),
        wall_clock_based_wait_enabled_(false),
        update_check_count_wait_enabled_(false),
        min_update_checks_needed_(kDefaultMinUpdateChecks),
        max_update_checks_allowed_(kDefaultMaxUpdateChecks),
        is_powerwash_allowed_(false),
        force_lock_down_(false),
        forced_lock_down_(false),
        use_p2p_for_downloading_(false),
        use_p2p_for_sharing_(false) {
    InitFromLsbValue();
  }

  OmahaRequestParams(SystemState* system_state,
                     const std::string& in_os_platform,
                     const std::string& in_os_version,
                     const std::string& in_os_sp,
                     const std::string& in_os_board,
                     const std::string& in_app_id,
                     const std::string& in_app_version,
                     const std::string& in_app_lang,
                     const std::string& in_target_channel,
                     const std::string& in_hwid,
                     const std::string& in_fw_version,
                     const std::string& in_ec_version,
                     bool in_delta_okay,
                     bool in_interactive,
                     const std::string& in_update_url,
                     bool in_update_disabled,
                     const std::string& in_target_version_prefix,
                     bool in_use_p2p_for_downloading,
                     bool in_use_p2p_for_sharing)
      : system_state_(system_state),
        os_platform_(in_os_platform),
        os_version_(in_os_version),
        os_sp_(in_os_sp),
        os_board_(in_os_board),
        board_app_id_(in_app_id),
        canary_app_id_(in_app_id),
        app_version_(in_app_version),
        app_lang_(in_app_lang),
        current_channel_(in_target_channel),
        target_channel_(in_target_channel),
        hwid_(in_hwid),
        fw_version_(in_fw_version),
        ec_version_(in_ec_version),
        delta_okay_(in_delta_okay),
        interactive_(in_interactive),
        update_url_(in_update_url),
        update_disabled_(in_update_disabled),
        target_version_prefix_(in_target_version_prefix),
        wall_clock_based_wait_enabled_(false),
        update_check_count_wait_enabled_(false),
        min_update_checks_needed_(kDefaultMinUpdateChecks),
        max_update_checks_allowed_(kDefaultMaxUpdateChecks),
        is_powerwash_allowed_(false),
        force_lock_down_(false),
        forced_lock_down_(false),
        use_p2p_for_downloading_(in_use_p2p_for_downloading),
        use_p2p_for_sharing_(in_use_p2p_for_sharing) {}

  // Setters and getters for the various properties.
  inline std::string os_platform() const { return os_platform_; }
  inline std::string os_version() const { return os_version_; }
  inline std::string os_sp() const { return os_sp_; }
  inline std::string os_board() const { return os_board_; }
  inline std::string board_app_id() const { return board_app_id_; }
  inline std::string canary_app_id() const { return canary_app_id_; }
  inline std::string app_lang() const { return app_lang_; }
  inline std::string hwid() const { return hwid_; }
  inline std::string fw_version() const { return fw_version_; }
  inline std::string ec_version() const { return ec_version_; }

  inline void set_app_version(const std::string& version) {
    app_version_ = version;
  }
  inline std::string app_version() const { return app_version_; }

  inline std::string current_channel() const { return current_channel_; }
  inline std::string target_channel() const { return target_channel_; }
  inline std::string download_channel() const { return download_channel_; }

  // Can client accept a delta ?
  inline void set_delta_okay(bool ok) { delta_okay_ = ok; }
  inline bool delta_okay() const { return delta_okay_; }

  // True if this is a user-initiated update check.
  inline void set_interactive(bool interactive) { interactive_ = interactive; }
  inline bool interactive() const { return interactive_; }

  inline void set_update_url(const std::string& url) { update_url_ = url; }
  inline std::string update_url() const { return update_url_; }

  inline void set_update_disabled(bool disabled) {
    update_disabled_ = disabled;
  }
  inline bool update_disabled() const { return update_disabled_; }

  inline void set_target_version_prefix(const std::string& prefix) {
    target_version_prefix_ = prefix;
  }

  inline std::string target_version_prefix() const {
    return target_version_prefix_;
  }

  inline void set_wall_clock_based_wait_enabled(bool enabled) {
    wall_clock_based_wait_enabled_ = enabled;
  }
  inline bool wall_clock_based_wait_enabled() const {
    return wall_clock_based_wait_enabled_;
  }

  inline void set_waiting_period(base::TimeDelta period) {
    waiting_period_ = period;
  }
  base::TimeDelta waiting_period() const { return waiting_period_; }

  inline void set_update_check_count_wait_enabled(bool enabled) {
    update_check_count_wait_enabled_ = enabled;
  }

  inline bool update_check_count_wait_enabled() const {
    return update_check_count_wait_enabled_;
  }

  inline void set_min_update_checks_needed(int64 min) {
    min_update_checks_needed_ = min;
  }
  inline int64 min_update_checks_needed() const {
    return min_update_checks_needed_;
  }

  inline void set_max_update_checks_allowed(int64 max) {
    max_update_checks_allowed_ = max;
  }
  inline int64 max_update_checks_allowed() const {
    return max_update_checks_allowed_;
  }

  inline void set_use_p2p_for_downloading(bool value) {
    use_p2p_for_downloading_ = value;
  }
  inline bool use_p2p_for_downloading() const {
    return use_p2p_for_downloading_;
  }

  inline void set_use_p2p_for_sharing(bool value) {
    use_p2p_for_sharing_ = value;
  }
  inline bool use_p2p_for_sharing() const {
    return use_p2p_for_sharing_;
  }

  inline void set_p2p_url(const std::string& value) {
    p2p_url_ = value;
  }
  inline std::string p2p_url() const {
    return p2p_url_;
  }

  // True if we're trying to update to a more stable channel.
  // i.e. index(target_channel) > index(current_channel).
  bool to_more_stable_channel() const;

  // Returns the app id corresponding to the current value of the
  // download channel.
  std::string GetAppId() const;

  // Suggested defaults
  static const char* const kAppId;
  static const char* const kOsPlatform;
  static const char* const kOsVersion;
  static const char* const kUpdateUrl;
  static const char* const kUpdateChannelKey;
  static const char* const kIsPowerwashAllowedKey;
  static const int64 kDefaultMinUpdateChecks = 0;
  static const int64 kDefaultMaxUpdateChecks = 8;

  // Initializes all the data in the object. Non-empty
  // |in_app_version| or |in_update_url| prevents automatic detection
  // of the parameter. Returns true on success, false otherwise.
  bool Init(const std::string& in_app_version,
            const std::string& in_update_url,
            bool in_interactive);

  // Permanently changes the release channel to |channel|. Performs a
  // powerwash, if required and allowed.
  // Returns true on success, false otherwise. Note: This call will fail if
  // there's a channel change pending already. This is to serialize all the
  // channel changes done by the user in order to avoid having to solve
  // numerous edge cases around ensuring the powerwash happens as intended in
  // all such cases.
  bool SetTargetChannel(const std::string& channel, bool is_powerwash_allowed);

  // Updates the download channel for this particular attempt from the current
  // value of target channel.  This method takes a "snapshot" of the current
  // value of target channel and uses it for all subsequent Omaha requests for
  // this attempt (i.e. initial request as well as download progress/error
  // event requests). The snapshot will be updated only when either this method
  // or Init is called again.
  void UpdateDownloadChannel();

  bool is_powerwash_allowed() const { return is_powerwash_allowed_; }

  // For unit-tests.
  void set_root(const std::string& root);
  void set_current_channel(const std::string& channel) {
    current_channel_ = channel;
  }

  // Enforce security mode for testing purposes.
  void SetLockDown(bool lock);

 private:
  FRIEND_TEST(OmahaRequestParamsTest, IsValidChannelTest);
  FRIEND_TEST(OmahaRequestParamsTest, ShouldLockDownTest);
  FRIEND_TEST(OmahaRequestParamsTest, ChannelIndexTest);
  FRIEND_TEST(OmahaRequestParamsTest, LsbPreserveTest);
  FRIEND_TEST(OmahaRequestParamsTest, CollectECFWVersionsTest);

  // Use a validator that is a non-static member of this class so that its
  // inputs can be mocked in unit tests (e.g., build type for IsValidChannel).
  typedef bool(OmahaRequestParams::*ValueValidator)(
      const std::string&) const;

  // Returns true if parameter values should be locked down for security
  // reasons. If this is an official build running in normal boot mode, all
  // values except the release channel are parsed only from the read-only rootfs
  // partition and the channel values are restricted to a pre-approved set.
  bool ShouldLockDown() const;

  // Returns true if |channel| is a valid channel, false otherwise. This method
  // restricts the channel value only if the image is official (see
  // IsOfficialBuild).
  bool IsValidChannel(const std::string& channel) const;

  // Returns the index of the given channel.
  int GetChannelIndex(const std::string& channel) const;

  // Returns True if we should store the fw/ec versions based on our hwid_.
  // Compares hwid to a set of whitelisted prefixes.
  bool CollectECFWVersions() const;

  // These are individual helper methods to initialize the said properties from
  // the LSB value.
  void SetTargetChannelFromLsbValue();
  void SetCurrentChannelFromLsbValue();
  void SetIsPowerwashAllowedFromLsbValue();

  // Initializes the required properties from the LSB value.
  void InitFromLsbValue();

  // Fetches the value for a given key from
  // /mnt/stateful_partition/etc/lsb-release if possible and |stateful_override|
  // is true. Failing that, it looks for the key in /etc/lsb-release. If
  // |validator| is non-NULL, uses it to validate and ignore invalid valies.
  std::string GetLsbValue(const std::string& key,
                          const std::string& default_value,
                          ValueValidator validator,
                          bool stateful_override) const;

  // Gets the machine type (e.g. "i686").
  std::string GetMachineType() const;

  // Global system context.
  SystemState* system_state_;

  // Basic properties of the OS and Application that go into the Omaha request.
  std::string os_platform_;
  std::string os_version_;
  std::string os_sp_;
  std::string os_board_;

  // The board app id identifies the app id for the board irrespective of the
  // channel that we're on. The canary app id identifies the app id to be used
  // iff we're in the canary-channel. These values could be different depending
  // on how the release tools are implemented.
  std::string board_app_id_;
  std::string canary_app_id_;

  std::string app_version_;
  std::string app_lang_;

  // The three channel values we deal with.
  // Current channel: is always the channel from /etc/lsb-release. It never
  // changes. It's just read in during initialization.
  std::string current_channel_;

  // Target channel: It starts off with the value of current channel. But if
  // the user changes the channel, then it'll have a different value. If the
  // user changes multiple times, target channel will always contain the most
  // recent change and is updated immediately to the user-selected value even
  // if we're in the middle of a download (as opposed to download channel
  // which gets updated only at the start of next download)
  std::string target_channel_;

  // The channel from which we're downloading the payload. This should normally
  // be the same as target channel. But if the user made another channel change
  // we started the download, then they'd be different, in which case, we'd
  // detect elsewhere that the target channel has been changed and cancel the
  // current download attempt.
  std::string download_channel_;

  std::string hwid_;  // Hardware Qualification ID of the client
  std::string fw_version_;  // Chrome OS Firmware Version.
  std::string ec_version_;  // Chrome OS EC Version.
  bool delta_okay_;  // If this client can accept a delta
  bool interactive_;   // Whether this is a user-initiated update check

  // The URL to send the Omaha request to.
  std::string update_url_;

  // True if we've been told to block updates per enterprise policy.
  bool update_disabled_;

  // Prefix of the target OS version that the enterprise wants this device
  // to be pinned to. It's empty otherwise.
  std::string target_version_prefix_;

  // True if scattering is enabled, in which case waiting_period_ specifies the
  // amount of absolute time that we've to wait for before sending a request to
  // Omaha.
  bool wall_clock_based_wait_enabled_;
  base::TimeDelta waiting_period_;

  // True if scattering is enabled to denote the number of update checks
  // we've to skip before we can send a request to Omaha. The min and max
  // values establish the bounds for a random number to be chosen within that
  // range to enable such a wait.
  bool update_check_count_wait_enabled_;
  int64 min_update_checks_needed_;
  int64 max_update_checks_allowed_;

  // True if we are allowed to do powerwash, if required, on a channel change.
  bool is_powerwash_allowed_;

  // When reading files, prepend root_ to the paths. Useful for testing.
  std::string root_;

  // Force security lock down for testing purposes.
  bool force_lock_down_;
  bool forced_lock_down_;

  // True if we may use p2p to download. This is based on owner
  // preferences and policy.
  bool use_p2p_for_downloading_;

  // True if we may use p2p to share. This is based on owner
  // preferences and policy.
  bool use_p2p_for_sharing_;

  // An URL to a local peer serving the requested payload or "" if no
  // such peer is available.
  std::string p2p_url_;

  // TODO(jaysri): Uncomment this after fixing unit tests, as part of
  // chromium-os:39752
  // DISALLOW_COPY_AND_ASSIGN(OmahaRequestParams);
};

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H__
