// 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.

#include "update_engine/payload_state.h"

#include <algorithm>
#include <string>

#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/format_macros.h>
#include <policy/device_policy.h>

#include "update_engine/clock.h"
#include "update_engine/constants.h"
#include "update_engine/hardware_interface.h"
#include "update_engine/install_plan.h"
#include "update_engine/omaha_request_params.h"
#include "update_engine/prefs.h"
#include "update_engine/real_dbus_wrapper.h"
#include "update_engine/system_state.h"
#include "update_engine/utils.h"

using base::Time;
using base::TimeDelta;
using std::min;
using std::string;

namespace chromeos_update_engine {

const TimeDelta PayloadState::kDurationSlack = TimeDelta::FromSeconds(600);

// We want to upperbound backoffs to 16 days
static const int kMaxBackoffDays = 16;

// We want to randomize retry attempts after the backoff by +/- 6 hours.
static const uint32_t kMaxBackoffFuzzMinutes = 12 * 60;

PayloadState::PayloadState()
    : prefs_(nullptr),
      using_p2p_for_downloading_(false),
      p2p_num_attempts_(0),
      payload_attempt_number_(0),
      full_payload_attempt_number_(0),
      url_index_(0),
      url_failure_count_(0),
      url_switch_count_(0),
      attempt_num_bytes_downloaded_(0),
      attempt_connection_type_(metrics::ConnectionType::kUnknown),
      attempt_type_(AttemptType::kUpdate) {
  for (int i = 0; i <= kNumDownloadSources; i++)
    total_bytes_downloaded_[i] = current_bytes_downloaded_[i] = 0;
}

bool PayloadState::Initialize(SystemState* system_state) {
  system_state_ = system_state;
  prefs_ = system_state_->prefs();
  powerwash_safe_prefs_ = system_state_->powerwash_safe_prefs();
  LoadResponseSignature();
  LoadPayloadAttemptNumber();
  LoadFullPayloadAttemptNumber();
  LoadUrlIndex();
  LoadUrlFailureCount();
  LoadUrlSwitchCount();
  LoadBackoffExpiryTime();
  LoadUpdateTimestampStart();
  // The LoadUpdateDurationUptime() method relies on LoadUpdateTimestampStart()
  // being called before it. Don't reorder.
  LoadUpdateDurationUptime();
  for (int i = 0; i < kNumDownloadSources; i++) {
    DownloadSource source = static_cast<DownloadSource>(i);
    LoadCurrentBytesDownloaded(source);
    LoadTotalBytesDownloaded(source);
  }
  LoadNumReboots();
  LoadNumResponsesSeen();
  LoadRollbackVersion();
  LoadP2PFirstAttemptTimestamp();
  LoadP2PNumAttempts();
  return true;
}

void PayloadState::SetResponse(const OmahaResponse& omaha_response) {
  // Always store the latest response.
  response_ = omaha_response;

  // Compute the candidate URLs first as they are used to calculate the
  // response signature so that a change in enterprise policy for
  // HTTP downloads being enabled or not could be honored as soon as the
  // next update check happens.
  ComputeCandidateUrls();

  // Check if the "signature" of this response (i.e. the fields we care about)
  // has changed.
  string new_response_signature = CalculateResponseSignature();
  bool has_response_changed = (response_signature_ != new_response_signature);

  // If the response has changed, we should persist the new signature and
  // clear away all the existing state.
  if (has_response_changed) {
    LOG(INFO) << "Resetting all persisted state as this is a new response";
    SetNumResponsesSeen(num_responses_seen_ + 1);
    SetResponseSignature(new_response_signature);
    ResetPersistedState();
    ReportUpdatesAbandonedEventCountMetric();
    return;
  }

  // This is the earliest point at which we can validate whether the URL index
  // we loaded from the persisted state is a valid value. If the response
  // hasn't changed but the URL index is invalid, it's indicative of some
  // tampering of the persisted state.
  if (static_cast<uint32_t>(url_index_) >= candidate_urls_.size()) {
    LOG(INFO) << "Resetting all payload state as the url index seems to have "
                 "been tampered with";
    ResetPersistedState();
    return;
  }

  // Update the current download source which depends on the latest value of
  // the response.
  UpdateCurrentDownloadSource();
}

void PayloadState::SetUsingP2PForDownloading(bool value) {
  using_p2p_for_downloading_ = value;
  // Update the current download source which depends on whether we are
  // using p2p or not.
  UpdateCurrentDownloadSource();
}

void PayloadState::DownloadComplete() {
  LOG(INFO) << "Payload downloaded successfully";
  IncrementPayloadAttemptNumber();
  IncrementFullPayloadAttemptNumber();
}

void PayloadState::DownloadProgress(size_t count) {
  if (count == 0)
    return;

  CalculateUpdateDurationUptime();
  UpdateBytesDownloaded(count);

  // We've received non-zero bytes from a recent download operation.  Since our
  // URL failure count is meant to penalize a URL only for consecutive
  // failures, downloading bytes successfully means we should reset the failure
  // count (as we know at least that the URL is working). In future, we can
  // design this to be more sophisticated to check for more intelligent failure
  // patterns, but right now, even 1 byte downloaded will mark the URL to be
  // good unless it hits 10 (or configured number of) consecutive failures
  // again.

  if (GetUrlFailureCount() == 0)
    return;

  LOG(INFO) << "Resetting failure count of Url" << GetUrlIndex()
            << " to 0 as we received " << count << " bytes successfully";
  SetUrlFailureCount(0);
}

void PayloadState::AttemptStarted(AttemptType attempt_type) {
  // Flush previous state from abnormal attempt failure, if any.
  ReportAndClearPersistedAttemptMetrics();

  attempt_type_ = attempt_type;

  ClockInterface *clock = system_state_->clock();
  attempt_start_time_boot_ = clock->GetBootTime();
  attempt_start_time_monotonic_ = clock->GetMonotonicTime();
  attempt_num_bytes_downloaded_ = 0;

  metrics::ConnectionType type;
  NetworkConnectionType network_connection_type;
  NetworkTethering tethering;
  RealDBusWrapper dbus_iface;
  ConnectionManager* connection_manager = system_state_->connection_manager();
  if (!connection_manager->GetConnectionProperties(&dbus_iface,
                                                   &network_connection_type,
                                                   &tethering)) {
    LOG(ERROR) << "Failed to determine connection type.";
    type = metrics::ConnectionType::kUnknown;
  } else {
    type = utils::GetConnectionType(network_connection_type, tethering);
  }
  attempt_connection_type_ = type;

  if (attempt_type == AttemptType::kUpdate)
    PersistAttemptMetrics();
}

void PayloadState::UpdateResumed() {
  LOG(INFO) << "Resuming an update that was previously started.";
  UpdateNumReboots();
  AttemptStarted(AttemptType::kUpdate);
}

void PayloadState::UpdateRestarted() {
  LOG(INFO) << "Starting a new update";
  ResetDownloadSourcesOnNewUpdate();
  SetNumReboots(0);
  AttemptStarted(AttemptType::kUpdate);
}

void PayloadState::UpdateSucceeded() {
  // Send the relevant metrics that are tracked in this class to UMA.
  CalculateUpdateDurationUptime();
  SetUpdateTimestampEnd(system_state_->clock()->GetWallclockTime());

  switch (attempt_type_) {
    case AttemptType::kUpdate:
      CollectAndReportAttemptMetrics(ErrorCode::kSuccess);
      CollectAndReportSuccessfulUpdateMetrics();
      ClearPersistedAttemptMetrics();
      break;

    case AttemptType::kRollback:
      metrics::ReportRollbackMetrics(system_state_,
                                     metrics::RollbackResult::kSuccess);
      break;
  }

  // Reset the number of responses seen since it counts from the last
  // successful update, e.g. now.
  SetNumResponsesSeen(0);

  CreateSystemUpdatedMarkerFile();
}

void PayloadState::UpdateFailed(ErrorCode error) {
  ErrorCode base_error = utils::GetBaseErrorCode(error);
  LOG(INFO) << "Updating payload state for error code: " << base_error
            << " (" << utils::CodeToString(base_error) << ")";

  if (candidate_urls_.size() == 0) {
    // This means we got this error even before we got a valid Omaha response
    // or don't have any valid candidates in the Omaha response.
    // So we should not advance the url_index_ in such cases.
    LOG(INFO) << "Ignoring failures until we get a valid Omaha response.";
    return;
  }

  switch (attempt_type_) {
    case AttemptType::kUpdate:
      CollectAndReportAttemptMetrics(base_error);
      ClearPersistedAttemptMetrics();
      break;

    case AttemptType::kRollback:
      metrics::ReportRollbackMetrics(system_state_,
                                     metrics::RollbackResult::kFailed);
      break;
  }

  switch (base_error) {
    // Errors which are good indicators of a problem with a particular URL or
    // the protocol used in the URL or entities in the communication channel
    // (e.g. proxies). We should try the next available URL in the next update
    // check to quickly recover from these errors.
    case ErrorCode::kPayloadHashMismatchError:
    case ErrorCode::kPayloadSizeMismatchError:
    case ErrorCode::kDownloadPayloadVerificationError:
    case ErrorCode::kDownloadPayloadPubKeyVerificationError:
    case ErrorCode::kSignedDeltaPayloadExpectedError:
    case ErrorCode::kDownloadInvalidMetadataMagicString:
    case ErrorCode::kDownloadSignatureMissingInManifest:
    case ErrorCode::kDownloadManifestParseError:
    case ErrorCode::kDownloadMetadataSignatureError:
    case ErrorCode::kDownloadMetadataSignatureVerificationError:
    case ErrorCode::kDownloadMetadataSignatureMismatch:
    case ErrorCode::kDownloadOperationHashVerificationError:
    case ErrorCode::kDownloadOperationExecutionError:
    case ErrorCode::kDownloadOperationHashMismatch:
    case ErrorCode::kDownloadInvalidMetadataSize:
    case ErrorCode::kDownloadInvalidMetadataSignature:
    case ErrorCode::kDownloadOperationHashMissingError:
    case ErrorCode::kDownloadMetadataSignatureMissingError:
    case ErrorCode::kPayloadMismatchedType:
    case ErrorCode::kUnsupportedMajorPayloadVersion:
    case ErrorCode::kUnsupportedMinorPayloadVersion:
      IncrementUrlIndex();
      break;

    // Errors which seem to be just transient network/communication related
    // failures and do not indicate any inherent problem with the URL itself.
    // So, we should keep the current URL but just increment the
    // failure count to give it more chances. This way, while we maximize our
    // chances of downloading from the URLs that appear earlier in the response
    // (because download from a local server URL that appears earlier in a
    // response is preferable than downloading from the next URL which could be
    // a internet URL and thus could be more expensive).

    case ErrorCode::kError:
    case ErrorCode::kDownloadTransferError:
    case ErrorCode::kDownloadWriteError:
    case ErrorCode::kDownloadStateInitializationError:
    case ErrorCode::kOmahaErrorInHTTPResponse:  // Aggregate for HTTP errors.
      IncrementFailureCount();
      break;

    // Errors which are not specific to a URL and hence shouldn't result in
    // the URL being penalized. This can happen in two cases:
    // 1. We haven't started downloading anything: These errors don't cost us
    // anything in terms of actual payload bytes, so we should just do the
    // regular retries at the next update check.
    // 2. We have successfully downloaded the payload: In this case, the
    // payload attempt number would have been incremented and would take care
    // of the backoff at the next update check.
    // In either case, there's no need to update URL index or failure count.
    case ErrorCode::kOmahaRequestError:
    case ErrorCode::kOmahaResponseHandlerError:
    case ErrorCode::kPostinstallRunnerError:
    case ErrorCode::kFilesystemCopierError:
    case ErrorCode::kInstallDeviceOpenError:
    case ErrorCode::kKernelDeviceOpenError:
    case ErrorCode::kDownloadNewPartitionInfoError:
    case ErrorCode::kNewRootfsVerificationError:
    case ErrorCode::kNewKernelVerificationError:
    case ErrorCode::kPostinstallBootedFromFirmwareB:
    case ErrorCode::kPostinstallFirmwareRONotUpdatable:
    case ErrorCode::kOmahaRequestEmptyResponseError:
    case ErrorCode::kOmahaRequestXMLParseError:
    case ErrorCode::kOmahaResponseInvalid:
    case ErrorCode::kOmahaUpdateIgnoredPerPolicy:
    case ErrorCode::kOmahaUpdateDeferredPerPolicy:
    case ErrorCode::kOmahaUpdateDeferredForBackoff:
    case ErrorCode::kPostinstallPowerwashError:
    case ErrorCode::kUpdateCanceledByChannelChange:
    case ErrorCode::kOmahaRequestXMLHasEntityDecl:
      LOG(INFO) << "Not incrementing URL index or failure count for this error";
      break;

    case ErrorCode::kSuccess:                            // success code
    case ErrorCode::kUmaReportedMax:                     // not an error code
    case ErrorCode::kOmahaRequestHTTPResponseBase:       // aggregated already
    case ErrorCode::kDevModeFlag:                       // not an error code
    case ErrorCode::kResumedFlag:                        // not an error code
    case ErrorCode::kTestImageFlag:                      // not an error code
    case ErrorCode::kTestOmahaUrlFlag:                   // not an error code
    case ErrorCode::kSpecialFlags:                       // not an error code
      // These shouldn't happen. Enumerating these  explicitly here so that we
      // can let the compiler warn about new error codes that are added to
      // action_processor.h but not added here.
      LOG(WARNING) << "Unexpected error code for UpdateFailed";
      break;

    // Note: Not adding a default here so as to let the compiler warn us of
    // any new enums that were added in the .h but not listed in this switch.
  }
}

bool PayloadState::ShouldBackoffDownload() {
  if (response_.disable_payload_backoff) {
    LOG(INFO) << "Payload backoff logic is disabled. "
                 "Can proceed with the download";
    return false;
  }
  if (GetUsingP2PForDownloading() && !GetP2PUrl().empty()) {
    LOG(INFO) << "Payload backoff logic is disabled because download "
              << "will happen from local peer (via p2p).";
    return false;
  }
  if (system_state_->request_params()->interactive()) {
    LOG(INFO) << "Payload backoff disabled for interactive update checks.";
    return false;
  }
  if (response_.is_delta_payload) {
    // If delta payloads fail, we want to fallback quickly to full payloads as
    // they are more likely to succeed. Exponential backoffs would greatly
    // slow down the fallback to full payloads.  So we don't backoff for delta
    // payloads.
    LOG(INFO) << "No backoffs for delta payloads. "
              << "Can proceed with the download";
    return false;
  }

  if (!system_state_->hardware()->IsOfficialBuild()) {
    // Backoffs are needed only for official builds. We do not want any delays
    // or update failures due to backoffs during testing or development.
    LOG(INFO) << "No backoffs for test/dev images. "
              << "Can proceed with the download";
    return false;
  }

  if (backoff_expiry_time_.is_null()) {
    LOG(INFO) << "No backoff expiry time has been set. "
              << "Can proceed with the download";
    return false;
  }

  if (backoff_expiry_time_ < Time::Now()) {
    LOG(INFO) << "The backoff expiry time ("
              << utils::ToString(backoff_expiry_time_)
              << ") has elapsed. Can proceed with the download";
    return false;
  }

  LOG(INFO) << "Cannot proceed with downloads as we need to backoff until "
            << utils::ToString(backoff_expiry_time_);
  return true;
}

void PayloadState::Rollback() {
  SetRollbackVersion(system_state_->request_params()->app_version());
  AttemptStarted(AttemptType::kRollback);
}

void PayloadState::IncrementPayloadAttemptNumber() {
  // Update the payload attempt number for both payload types: full and delta.
  SetPayloadAttemptNumber(GetPayloadAttemptNumber() + 1);

  // Report the metric every time the value is incremented.
  string metric = "Installer.PayloadAttemptNumber";
  int value = GetPayloadAttemptNumber();

  LOG(INFO) << "Uploading " << value << " (count) for metric " <<  metric;
  system_state_->metrics_lib()->SendToUMA(
       metric,
       value,
       1,    // min value
       50,   // max value
       kNumDefaultUmaBuckets);
}

void PayloadState::IncrementFullPayloadAttemptNumber() {
  // Update the payload attempt number for full payloads and the backoff time.
  if (response_.is_delta_payload) {
    LOG(INFO) << "Not incrementing payload attempt number for delta payloads";
    return;
  }

  LOG(INFO) << "Incrementing the full payload attempt number";
  SetFullPayloadAttemptNumber(GetFullPayloadAttemptNumber() + 1);
  UpdateBackoffExpiryTime();

  // Report the metric every time the value is incremented.
  string metric = "Installer.FullPayloadAttemptNumber";
  int value = GetFullPayloadAttemptNumber();

  LOG(INFO) << "Uploading " << value << " (count) for metric " <<  metric;
  system_state_->metrics_lib()->SendToUMA(
       metric,
       value,
       1,    // min value
       50,   // max value
       kNumDefaultUmaBuckets);
}

void PayloadState::IncrementUrlIndex() {
  uint32_t next_url_index = GetUrlIndex() + 1;
  if (next_url_index < candidate_urls_.size()) {
    LOG(INFO) << "Incrementing the URL index for next attempt";
    SetUrlIndex(next_url_index);
  } else {
    LOG(INFO) << "Resetting the current URL index (" << GetUrlIndex() << ") to "
              << "0 as we only have " << candidate_urls_.size()
              << " candidate URL(s)";
    SetUrlIndex(0);
    IncrementPayloadAttemptNumber();
    IncrementFullPayloadAttemptNumber();
  }

  // If we have multiple URLs, record that we just switched to another one
  if (candidate_urls_.size() > 1)
    SetUrlSwitchCount(url_switch_count_ + 1);

  // Whenever we update the URL index, we should also clear the URL failure
  // count so we can start over fresh for the new URL.
  SetUrlFailureCount(0);
}

void PayloadState::IncrementFailureCount() {
  uint32_t next_url_failure_count = GetUrlFailureCount() + 1;
  if (next_url_failure_count < response_.max_failure_count_per_url) {
    LOG(INFO) << "Incrementing the URL failure count";
    SetUrlFailureCount(next_url_failure_count);
  } else {
    LOG(INFO) << "Reached max number of failures for Url" << GetUrlIndex()
              << ". Trying next available URL";
    IncrementUrlIndex();
  }
}

void PayloadState::UpdateBackoffExpiryTime() {
  if (response_.disable_payload_backoff) {
    LOG(INFO) << "Resetting backoff expiry time as payload backoff is disabled";
    SetBackoffExpiryTime(Time());
    return;
  }

  if (GetFullPayloadAttemptNumber() == 0) {
    SetBackoffExpiryTime(Time());
    return;
  }

  // Since we're doing left-shift below, make sure we don't shift more
  // than this. E.g. if int is 4-bytes, don't left-shift more than 30 bits,
  // since we don't expect value of kMaxBackoffDays to be more than 100 anyway.
  int num_days = 1;  // the value to be shifted.
  const int kMaxShifts = (sizeof(num_days) * 8) - 2;

  // Normal backoff days is 2 raised to (payload_attempt_number - 1).
  // E.g. if payload_attempt_number is over 30, limit power to 30.
  int power = min(GetFullPayloadAttemptNumber() - 1, kMaxShifts);

  // The number of days is the minimum of 2 raised to (payload_attempt_number
  // - 1) or kMaxBackoffDays.
  num_days = min(num_days << power, kMaxBackoffDays);

  // We don't want all retries to happen exactly at the same time when
  // retrying after backoff. So add some random minutes to fuzz.
  int fuzz_minutes = utils::FuzzInt(0, kMaxBackoffFuzzMinutes);
  TimeDelta next_backoff_interval = TimeDelta::FromDays(num_days) +
                                    TimeDelta::FromMinutes(fuzz_minutes);
  LOG(INFO) << "Incrementing the backoff expiry time by "
            << utils::FormatTimeDelta(next_backoff_interval);
  SetBackoffExpiryTime(Time::Now() + next_backoff_interval);
}

void PayloadState::UpdateCurrentDownloadSource() {
  current_download_source_ = kNumDownloadSources;

  if (using_p2p_for_downloading_) {
    current_download_source_ = kDownloadSourceHttpPeer;
  } else if (GetUrlIndex() < candidate_urls_.size())  {
    string current_url = candidate_urls_[GetUrlIndex()];
    if (StartsWithASCII(current_url, "https://", false))
      current_download_source_ = kDownloadSourceHttpsServer;
    else if (StartsWithASCII(current_url, "http://", false))
      current_download_source_ = kDownloadSourceHttpServer;
  }

  LOG(INFO) << "Current download source: "
            << utils::ToString(current_download_source_);
}

void PayloadState::UpdateBytesDownloaded(size_t count) {
  SetCurrentBytesDownloaded(
      current_download_source_,
      GetCurrentBytesDownloaded(current_download_source_) + count,
      false);
  SetTotalBytesDownloaded(
      current_download_source_,
      GetTotalBytesDownloaded(current_download_source_) + count,
      false);

  attempt_num_bytes_downloaded_ += count;
}

PayloadType PayloadState::CalculatePayloadType() {
  PayloadType payload_type;
  OmahaRequestParams* params = system_state_->request_params();
  if (response_.is_delta_payload) {
    payload_type = kPayloadTypeDelta;
  } else if (params->delta_okay()) {
    payload_type = kPayloadTypeFull;
  } else {  // Full payload, delta was not allowed by request.
    payload_type = kPayloadTypeForcedFull;
  }
  return payload_type;
}

// TODO(zeuthen): Currently we don't report the UpdateEngine.Attempt.*
// metrics if the attempt ends abnormally, e.g. if the update_engine
// process crashes or the device is rebooted. See
// http://crbug.com/357676
void PayloadState::CollectAndReportAttemptMetrics(ErrorCode code) {
  int attempt_number = GetPayloadAttemptNumber();

  PayloadType payload_type = CalculatePayloadType();

  int64_t payload_size = response_.size;

  int64_t payload_bytes_downloaded = attempt_num_bytes_downloaded_;

  ClockInterface *clock = system_state_->clock();
  TimeDelta duration = clock->GetBootTime() - attempt_start_time_boot_;
  TimeDelta duration_uptime = clock->GetMonotonicTime() -
      attempt_start_time_monotonic_;

  int64_t payload_download_speed_bps = 0;
  int64_t usec = duration_uptime.InMicroseconds();
  if (usec > 0) {
    double sec = static_cast<double>(usec) / Time::kMicrosecondsPerSecond;
    double bps = static_cast<double>(payload_bytes_downloaded) / sec;
    payload_download_speed_bps = static_cast<int64_t>(bps);
  }

  DownloadSource download_source = current_download_source_;

  metrics::DownloadErrorCode payload_download_error_code =
    metrics::DownloadErrorCode::kUnset;
  ErrorCode internal_error_code = ErrorCode::kSuccess;
  metrics::AttemptResult attempt_result = utils::GetAttemptResult(code);

  // Add additional detail to AttemptResult
  switch (attempt_result) {
    case metrics::AttemptResult::kPayloadDownloadError:
      payload_download_error_code = utils::GetDownloadErrorCode(code);
      break;

    case metrics::AttemptResult::kInternalError:
      internal_error_code = code;
      break;

    // Explicit fall-through for cases where we do not have additional
    // detail. We avoid the default keyword to force people adding new
    // AttemptResult values to visit this code and examine whether
    // additional detail is needed.
    case metrics::AttemptResult::kUpdateSucceeded:
    case metrics::AttemptResult::kMetadataMalformed:
    case metrics::AttemptResult::kOperationMalformed:
    case metrics::AttemptResult::kOperationExecutionError:
    case metrics::AttemptResult::kMetadataVerificationFailed:
    case metrics::AttemptResult::kPayloadVerificationFailed:
    case metrics::AttemptResult::kVerificationFailed:
    case metrics::AttemptResult::kPostInstallFailed:
    case metrics::AttemptResult::kAbnormalTermination:
    case metrics::AttemptResult::kNumConstants:
    case metrics::AttemptResult::kUnset:
      break;
  }

  metrics::ReportUpdateAttemptMetrics(system_state_,
                                      attempt_number,
                                      payload_type,
                                      duration,
                                      duration_uptime,
                                      payload_size,
                                      payload_bytes_downloaded,
                                      payload_download_speed_bps,
                                      download_source,
                                      attempt_result,
                                      internal_error_code,
                                      payload_download_error_code,
                                      attempt_connection_type_);
}

void PayloadState::PersistAttemptMetrics() {
  // TODO(zeuthen): For now we only persist whether an attempt was in
  // progress and not values/metrics related to the attempt. This
  // means that when this happens, of all the UpdateEngine.Attempt.*
  // metrics, only UpdateEngine.Attempt.Result is reported (with the
  // value |kAbnormalTermination|). In the future we might want to
  // persist more data so we can report other metrics in the
  // UpdateEngine.Attempt.* namespace when this happens.
  prefs_->SetBoolean(kPrefsAttemptInProgress, true);
}

void PayloadState::ClearPersistedAttemptMetrics() {
  prefs_->Delete(kPrefsAttemptInProgress);
}

void PayloadState::ReportAndClearPersistedAttemptMetrics() {
  bool attempt_in_progress = false;
  if (!prefs_->GetBoolean(kPrefsAttemptInProgress, &attempt_in_progress))
    return;
  if (!attempt_in_progress)
    return;

  metrics::ReportAbnormallyTerminatedUpdateAttemptMetrics(system_state_);

  ClearPersistedAttemptMetrics();
}

void PayloadState::CollectAndReportSuccessfulUpdateMetrics() {
  string metric;

  // Report metrics collected from all known download sources to UMA.
  int64_t successful_bytes_by_source[kNumDownloadSources];
  int64_t total_bytes_by_source[kNumDownloadSources];
  int64_t successful_bytes = 0;
  int64_t total_bytes = 0;
  int64_t successful_mbs = 0;
  int64_t total_mbs = 0;

  for (int i = 0; i < kNumDownloadSources; i++) {
    DownloadSource source = static_cast<DownloadSource>(i);
    int64_t bytes;

    // Only consider this download source (and send byte counts) as
    // having been used if we downloaded a non-trivial amount of bytes
    // (e.g. at least 1 MiB) that contributed to the final success of
    // the update. Otherwise we're going to end up with a lot of
    // zero-byte events in the histogram.

    bytes = GetCurrentBytesDownloaded(source);
    successful_bytes_by_source[i] = bytes;
    successful_bytes += bytes;
    successful_mbs += bytes / kNumBytesInOneMiB;
    SetCurrentBytesDownloaded(source, 0, true);

    bytes = GetTotalBytesDownloaded(source);
    total_bytes_by_source[i] = bytes;
    total_bytes += bytes;
    total_mbs += bytes / kNumBytesInOneMiB;
    SetTotalBytesDownloaded(source, 0, true);
  }

  int download_overhead_percentage = 0;
  if (successful_bytes > 0) {
    download_overhead_percentage = (total_bytes - successful_bytes) * 100ULL /
                                   successful_bytes;
  }

  int url_switch_count = static_cast<int>(url_switch_count_);

  int reboot_count = GetNumReboots();

  SetNumReboots(0);

  TimeDelta duration = GetUpdateDuration();
  TimeDelta duration_uptime = GetUpdateDurationUptime();

  prefs_->Delete(kPrefsUpdateTimestampStart);
  prefs_->Delete(kPrefsUpdateDurationUptime);

  PayloadType payload_type = CalculatePayloadType();

  int64_t payload_size = response_.size;

  int attempt_count = GetPayloadAttemptNumber();

  int updates_abandoned_count = num_responses_seen_ - 1;

  metrics::ReportSuccessfulUpdateMetrics(system_state_,
                                         attempt_count,
                                         updates_abandoned_count,
                                         payload_type,
                                         payload_size,
                                         total_bytes_by_source,
                                         download_overhead_percentage,
                                         duration,
                                         reboot_count,
                                         url_switch_count);

  // TODO(zeuthen): This is the old metric reporting code which is
  // slated for removal soon. See http://crbug.com/355745 for details.

  // The old metrics code is using MiB's instead of bytes to calculate
  // the overhead which due to rounding makes the numbers slightly
  // different.
  download_overhead_percentage = 0;
  if (successful_mbs > 0) {
    download_overhead_percentage = (total_mbs - successful_mbs) * 100ULL /
                                   successful_mbs;
  }

  int download_sources_used = 0;
  for (int i = 0; i < kNumDownloadSources; i++) {
    DownloadSource source = static_cast<DownloadSource>(i);
    const int kMaxMiBs = 10240;  // Anything above 10GB goes in the last bucket.
    int64_t mbs;

    // Only consider this download source (and send byte counts) as
    // having been used if we downloaded a non-trivial amount of bytes
    // (e.g. at least 1 MiB) that contributed to the final success of
    // the update. Otherwise we're going to end up with a lot of
    // zero-byte events in the histogram.

    mbs = successful_bytes_by_source[i] / kNumBytesInOneMiB;
    if (mbs > 0) {
      metric = "Installer.SuccessfulMBsDownloadedFrom" +
          utils::ToString(source);
      LOG(INFO) << "Uploading " << mbs << " (MBs) for metric " << metric;
      system_state_->metrics_lib()->SendToUMA(metric,
                                              mbs,
                                              0,  // min
                                              kMaxMiBs,
                                              kNumDefaultUmaBuckets);
    }

    mbs = total_bytes_by_source[i] / kNumBytesInOneMiB;
    if (mbs > 0) {
      metric = "Installer.TotalMBsDownloadedFrom" + utils::ToString(source);
      LOG(INFO) << "Uploading " << mbs << " (MBs) for metric " << metric;
      system_state_->metrics_lib()->SendToUMA(metric,
                                              mbs,
                                              0,  // min
                                              kMaxMiBs,
                                              kNumDefaultUmaBuckets);
      download_sources_used |= (1 << i);
    }
  }

  metric = "Installer.DownloadSourcesUsed";
  LOG(INFO) << "Uploading 0x" << std::hex << download_sources_used
            << " (bit flags) for metric " << metric;
  int num_buckets = min(1 << kNumDownloadSources, kNumDefaultUmaBuckets);
  system_state_->metrics_lib()->SendToUMA(metric,
                                          download_sources_used,
                                          0,  // min
                                          1 << kNumDownloadSources,
                                          num_buckets);

  metric = "Installer.DownloadOverheadPercentage";
  LOG(INFO) << "Uploading " << download_overhead_percentage
            << "% for metric " << metric;
  system_state_->metrics_lib()->SendToUMA(metric,
                                          download_overhead_percentage,
                                          0,     // min: 0% overhead
                                          1000,  // max: 1000% overhead
                                          kNumDefaultUmaBuckets);

  metric = "Installer.UpdateURLSwitches";
  LOG(INFO) << "Uploading " << url_switch_count
            << " (count) for metric " << metric;
  system_state_->metrics_lib()->SendToUMA(
       metric,
       url_switch_count,
       0,    // min value
       100,  // max value
       kNumDefaultUmaBuckets);

  metric = "Installer.UpdateNumReboots";
  LOG(INFO) << "Uploading reboot count of " << reboot_count << " for metric "
            <<  metric;
  system_state_->metrics_lib()->SendToUMA(
      metric,
      reboot_count,  // sample
      0,    // min = 0.
      50,   // max
      25);  // buckets

  metric = "Installer.UpdateDurationMinutes";
  system_state_->metrics_lib()->SendToUMA(
       metric,
       static_cast<int>(duration.InMinutes()),
       1,             // min: 1 minute
       365*24*60,     // max: 1 year (approx)
       kNumDefaultUmaBuckets);
  LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration)
            << " for metric " <<  metric;

  metric = "Installer.UpdateDurationUptimeMinutes";
  system_state_->metrics_lib()->SendToUMA(
       metric,
       static_cast<int>(duration_uptime.InMinutes()),
       1,             // min: 1 minute
       30*24*60,      // max: 1 month (approx)
       kNumDefaultUmaBuckets);
  LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration_uptime)
            << " for metric " <<  metric;

  metric = "Installer.PayloadFormat";
  system_state_->metrics_lib()->SendEnumToUMA(
      metric,
      payload_type,
      kNumPayloadTypes);
  LOG(INFO) << "Uploading " << utils::ToString(payload_type)
            << " for metric " <<  metric;

  metric = "Installer.AttemptsCount.Total";
  system_state_->metrics_lib()->SendToUMA(
       metric,
       attempt_count,
       1,      // min
       50,     // max
       kNumDefaultUmaBuckets);
  LOG(INFO) << "Uploading " << attempt_count
            << " for metric " <<  metric;

  metric = "Installer.UpdatesAbandonedCount";
  LOG(INFO) << "Uploading " << updates_abandoned_count
            << " (count) for metric " <<  metric;
  system_state_->metrics_lib()->SendToUMA(
       metric,
       updates_abandoned_count,
       0,    // min value
       100,  // max value
       kNumDefaultUmaBuckets);
}

void PayloadState::UpdateNumReboots() {
  // We only update the reboot count when the system has been detected to have
  // been rebooted.
  if (!system_state_->system_rebooted()) {
    return;
  }

  SetNumReboots(GetNumReboots() + 1);
}

void PayloadState::SetNumReboots(uint32_t num_reboots) {
  CHECK(prefs_);
  num_reboots_ = num_reboots;
  prefs_->SetInt64(kPrefsNumReboots, num_reboots);
  LOG(INFO) << "Number of Reboots during current update attempt = "
            << num_reboots_;
}

void PayloadState::ResetPersistedState() {
  SetPayloadAttemptNumber(0);
  SetFullPayloadAttemptNumber(0);
  SetUrlIndex(0);
  SetUrlFailureCount(0);
  SetUrlSwitchCount(0);
  UpdateBackoffExpiryTime();  // This will reset the backoff expiry time.
  SetUpdateTimestampStart(system_state_->clock()->GetWallclockTime());
  SetUpdateTimestampEnd(Time());  // Set to null time
  SetUpdateDurationUptime(TimeDelta::FromSeconds(0));
  ResetDownloadSourcesOnNewUpdate();
  ResetRollbackVersion();
  SetP2PNumAttempts(0);
  SetP2PFirstAttemptTimestamp(Time());  // Set to null time
  SetScatteringWaitPeriod(TimeDelta());
}

void PayloadState::ResetRollbackVersion() {
  CHECK(powerwash_safe_prefs_);
  rollback_version_ = "";
  powerwash_safe_prefs_->Delete(kPrefsRollbackVersion);
}

void PayloadState::ResetDownloadSourcesOnNewUpdate() {
  for (int i = 0; i < kNumDownloadSources; i++) {
    DownloadSource source = static_cast<DownloadSource>(i);
    SetCurrentBytesDownloaded(source, 0, true);
    // Note: Not resetting the TotalBytesDownloaded as we want that metric
    // to count the bytes downloaded across various update attempts until
    // we have successfully applied the update.
  }
}

int64_t PayloadState::GetPersistedValue(const string& key) {
  CHECK(prefs_);
  if (!prefs_->Exists(key))
    return 0;

  int64_t stored_value;
  if (!prefs_->GetInt64(key, &stored_value))
    return 0;

  if (stored_value < 0) {
    LOG(ERROR) << key << ": Invalid value (" << stored_value
               << ") in persisted state. Defaulting to 0";
    return 0;
  }

  return stored_value;
}

string PayloadState::CalculateResponseSignature() {
  string response_sign = base::StringPrintf(
      "NumURLs = %d\n", static_cast<int>(candidate_urls_.size()));

  for (size_t i = 0; i < candidate_urls_.size(); i++)
    response_sign += base::StringPrintf("Candidate Url%d = %s\n",
                                        static_cast<int>(i),
                                        candidate_urls_[i].c_str());

  response_sign += base::StringPrintf(
      "Payload Size = %ju\n"
      "Payload Sha256 Hash = %s\n"
      "Metadata Size = %ju\n"
      "Metadata Signature = %s\n"
      "Is Delta Payload = %d\n"
      "Max Failure Count Per Url = %d\n"
      "Disable Payload Backoff = %d\n",
      static_cast<uintmax_t>(response_.size),
      response_.hash.c_str(),
      static_cast<uintmax_t>(response_.metadata_size),
      response_.metadata_signature.c_str(),
      response_.is_delta_payload,
      response_.max_failure_count_per_url,
      response_.disable_payload_backoff);
  return response_sign;
}

void PayloadState::LoadResponseSignature() {
  CHECK(prefs_);
  string stored_value;
  if (prefs_->Exists(kPrefsCurrentResponseSignature) &&
      prefs_->GetString(kPrefsCurrentResponseSignature, &stored_value)) {
    SetResponseSignature(stored_value);
  }
}

void PayloadState::SetResponseSignature(const string& response_signature) {
  CHECK(prefs_);
  response_signature_ = response_signature;
  LOG(INFO) << "Current Response Signature = \n" << response_signature_;
  prefs_->SetString(kPrefsCurrentResponseSignature, response_signature_);
}

void PayloadState::LoadPayloadAttemptNumber() {
  SetPayloadAttemptNumber(GetPersistedValue(kPrefsPayloadAttemptNumber));
}

void PayloadState::LoadFullPayloadAttemptNumber() {
  SetFullPayloadAttemptNumber(GetPersistedValue(
      kPrefsFullPayloadAttemptNumber));
}

void PayloadState::SetPayloadAttemptNumber(int payload_attempt_number) {
  CHECK(prefs_);
  payload_attempt_number_ = payload_attempt_number;
  LOG(INFO) << "Payload Attempt Number = " << payload_attempt_number_;
  prefs_->SetInt64(kPrefsPayloadAttemptNumber, payload_attempt_number_);
}

void PayloadState::SetFullPayloadAttemptNumber(
    int full_payload_attempt_number) {
  CHECK(prefs_);
  full_payload_attempt_number_ = full_payload_attempt_number;
  LOG(INFO) << "Full Payload Attempt Number = " << full_payload_attempt_number_;
  prefs_->SetInt64(kPrefsFullPayloadAttemptNumber,
      full_payload_attempt_number_);
}

void PayloadState::LoadUrlIndex() {
  SetUrlIndex(GetPersistedValue(kPrefsCurrentUrlIndex));
}

void PayloadState::SetUrlIndex(uint32_t url_index) {
  CHECK(prefs_);
  url_index_ = url_index;
  LOG(INFO) << "Current URL Index = " << url_index_;
  prefs_->SetInt64(kPrefsCurrentUrlIndex, url_index_);

  // Also update the download source, which is purely dependent on the
  // current URL index alone.
  UpdateCurrentDownloadSource();
}

void PayloadState::LoadScatteringWaitPeriod() {
  SetScatteringWaitPeriod(
      TimeDelta::FromSeconds(GetPersistedValue(kPrefsWallClockWaitPeriod)));
}

void PayloadState::SetScatteringWaitPeriod(TimeDelta wait_period) {
  CHECK(prefs_);
  scattering_wait_period_ = wait_period;
  LOG(INFO) << "Scattering Wait Period (seconds) = "
            << scattering_wait_period_.InSeconds();
  if (scattering_wait_period_.InSeconds() > 0) {
    prefs_->SetInt64(kPrefsWallClockWaitPeriod,
                     scattering_wait_period_.InSeconds());
  } else {
    prefs_->Delete(kPrefsWallClockWaitPeriod);
  }
}

void PayloadState::LoadUrlSwitchCount() {
  SetUrlSwitchCount(GetPersistedValue(kPrefsUrlSwitchCount));
}

void PayloadState::SetUrlSwitchCount(uint32_t url_switch_count) {
  CHECK(prefs_);
  url_switch_count_ = url_switch_count;
  LOG(INFO) << "URL Switch Count = " << url_switch_count_;
  prefs_->SetInt64(kPrefsUrlSwitchCount, url_switch_count_);
}

void PayloadState::LoadUrlFailureCount() {
  SetUrlFailureCount(GetPersistedValue(kPrefsCurrentUrlFailureCount));
}

void PayloadState::SetUrlFailureCount(uint32_t url_failure_count) {
  CHECK(prefs_);
  url_failure_count_ = url_failure_count;
  LOG(INFO) << "Current URL (Url" << GetUrlIndex()
            << ")'s Failure Count = " << url_failure_count_;
  prefs_->SetInt64(kPrefsCurrentUrlFailureCount, url_failure_count_);
}

void PayloadState::LoadBackoffExpiryTime() {
  CHECK(prefs_);
  int64_t stored_value;
  if (!prefs_->Exists(kPrefsBackoffExpiryTime))
    return;

  if (!prefs_->GetInt64(kPrefsBackoffExpiryTime, &stored_value))
    return;

  Time stored_time = Time::FromInternalValue(stored_value);
  if (stored_time > Time::Now() + TimeDelta::FromDays(kMaxBackoffDays)) {
    LOG(ERROR) << "Invalid backoff expiry time ("
               << utils::ToString(stored_time)
               << ") in persisted state. Resetting.";
    stored_time = Time();
  }
  SetBackoffExpiryTime(stored_time);
}

void PayloadState::SetBackoffExpiryTime(const Time& new_time) {
  CHECK(prefs_);
  backoff_expiry_time_ = new_time;
  LOG(INFO) << "Backoff Expiry Time = "
            << utils::ToString(backoff_expiry_time_);
  prefs_->SetInt64(kPrefsBackoffExpiryTime,
                   backoff_expiry_time_.ToInternalValue());
}

TimeDelta PayloadState::GetUpdateDuration() {
  Time end_time = update_timestamp_end_.is_null()
    ? system_state_->clock()->GetWallclockTime() :
      update_timestamp_end_;
  return end_time - update_timestamp_start_;
}

void PayloadState::LoadUpdateTimestampStart() {
  int64_t stored_value;
  Time stored_time;

  CHECK(prefs_);

  Time now = system_state_->clock()->GetWallclockTime();

  if (!prefs_->Exists(kPrefsUpdateTimestampStart)) {
    // The preference missing is not unexpected - in that case, just
    // use the current time as start time
    stored_time = now;
  } else if (!prefs_->GetInt64(kPrefsUpdateTimestampStart, &stored_value)) {
    LOG(ERROR) << "Invalid UpdateTimestampStart value. Resetting.";
    stored_time = now;
  } else {
    stored_time = Time::FromInternalValue(stored_value);
  }

  // Sanity check: If the time read from disk is in the future
  // (modulo some slack to account for possible NTP drift
  // adjustments), something is fishy and we should report and
  // reset.
  TimeDelta duration_according_to_stored_time = now - stored_time;
  if (duration_according_to_stored_time < -kDurationSlack) {
    LOG(ERROR) << "The UpdateTimestampStart value ("
               << utils::ToString(stored_time)
               << ") in persisted state is "
               << utils::FormatTimeDelta(duration_according_to_stored_time)
               << " in the future. Resetting.";
    stored_time = now;
  }

  SetUpdateTimestampStart(stored_time);
}

void PayloadState::SetUpdateTimestampStart(const Time& value) {
  CHECK(prefs_);
  update_timestamp_start_ = value;
  prefs_->SetInt64(kPrefsUpdateTimestampStart,
                   update_timestamp_start_.ToInternalValue());
  LOG(INFO) << "Update Timestamp Start = "
            << utils::ToString(update_timestamp_start_);
}

void PayloadState::SetUpdateTimestampEnd(const Time& value) {
  update_timestamp_end_ = value;
  LOG(INFO) << "Update Timestamp End = "
            << utils::ToString(update_timestamp_end_);
}

TimeDelta PayloadState::GetUpdateDurationUptime() {
  return update_duration_uptime_;
}

void PayloadState::LoadUpdateDurationUptime() {
  int64_t stored_value;
  TimeDelta stored_delta;

  CHECK(prefs_);

  if (!prefs_->Exists(kPrefsUpdateDurationUptime)) {
    // The preference missing is not unexpected - in that case, just
    // we'll use zero as the delta
  } else if (!prefs_->GetInt64(kPrefsUpdateDurationUptime, &stored_value)) {
    LOG(ERROR) << "Invalid UpdateDurationUptime value. Resetting.";
    stored_delta = TimeDelta::FromSeconds(0);
  } else {
    stored_delta = TimeDelta::FromInternalValue(stored_value);
  }

  // Sanity-check: Uptime can never be greater than the wall-clock
  // difference (modulo some slack). If it is, report and reset
  // to the wall-clock difference.
  TimeDelta diff = GetUpdateDuration() - stored_delta;
  if (diff < -kDurationSlack) {
    LOG(ERROR) << "The UpdateDurationUptime value ("
               << utils::FormatTimeDelta(stored_delta)
               << ") in persisted state is "
               << utils::FormatTimeDelta(diff)
               << " larger than the wall-clock delta. Resetting.";
    stored_delta = update_duration_current_;
  }

  SetUpdateDurationUptime(stored_delta);
}

void PayloadState::LoadNumReboots() {
  SetNumReboots(GetPersistedValue(kPrefsNumReboots));
}

void PayloadState::LoadRollbackVersion() {
  CHECK(powerwash_safe_prefs_);
  string rollback_version;
  if (powerwash_safe_prefs_->GetString(kPrefsRollbackVersion,
                                       &rollback_version)) {
    SetRollbackVersion(rollback_version);
  }
}

void PayloadState::SetRollbackVersion(const string& rollback_version) {
  CHECK(powerwash_safe_prefs_);
  LOG(INFO) << "Blacklisting version "<< rollback_version;
  rollback_version_ = rollback_version;
  powerwash_safe_prefs_->SetString(kPrefsRollbackVersion, rollback_version);
}

void PayloadState::SetUpdateDurationUptimeExtended(const TimeDelta& value,
                                                   const Time& timestamp,
                                                   bool use_logging) {
  CHECK(prefs_);
  update_duration_uptime_ = value;
  update_duration_uptime_timestamp_ = timestamp;
  prefs_->SetInt64(kPrefsUpdateDurationUptime,
                   update_duration_uptime_.ToInternalValue());
  if (use_logging) {
    LOG(INFO) << "Update Duration Uptime = "
              << utils::FormatTimeDelta(update_duration_uptime_);
  }
}

void PayloadState::SetUpdateDurationUptime(const TimeDelta& value) {
  Time now = system_state_->clock()->GetMonotonicTime();
  SetUpdateDurationUptimeExtended(value, now, true);
}

void PayloadState::CalculateUpdateDurationUptime() {
  Time now = system_state_->clock()->GetMonotonicTime();
  TimeDelta uptime_since_last_update = now - update_duration_uptime_timestamp_;
  TimeDelta new_uptime = update_duration_uptime_ + uptime_since_last_update;
  // We're frequently called so avoid logging this write
  SetUpdateDurationUptimeExtended(new_uptime, now, false);
}

string PayloadState::GetPrefsKey(const string& prefix, DownloadSource source) {
  return prefix + "-from-" + utils::ToString(source);
}

void PayloadState::LoadCurrentBytesDownloaded(DownloadSource source) {
  string key = GetPrefsKey(kPrefsCurrentBytesDownloaded, source);
  SetCurrentBytesDownloaded(source, GetPersistedValue(key), true);
}

void PayloadState::SetCurrentBytesDownloaded(
    DownloadSource source,
    uint64_t current_bytes_downloaded,
    bool log) {
  CHECK(prefs_);

  if (source >= kNumDownloadSources)
    return;

  // Update the in-memory value.
  current_bytes_downloaded_[source] = current_bytes_downloaded;

  string prefs_key = GetPrefsKey(kPrefsCurrentBytesDownloaded, source);
  prefs_->SetInt64(prefs_key, current_bytes_downloaded);
  LOG_IF(INFO, log) << "Current bytes downloaded for "
                    << utils::ToString(source) << " = "
                    << GetCurrentBytesDownloaded(source);
}

void PayloadState::LoadTotalBytesDownloaded(DownloadSource source) {
  string key = GetPrefsKey(kPrefsTotalBytesDownloaded, source);
  SetTotalBytesDownloaded(source, GetPersistedValue(key), true);
}

void PayloadState::SetTotalBytesDownloaded(
    DownloadSource source,
    uint64_t total_bytes_downloaded,
    bool log) {
  CHECK(prefs_);

  if (source >= kNumDownloadSources)
    return;

  // Update the in-memory value.
  total_bytes_downloaded_[source] = total_bytes_downloaded;

  // Persist.
  string prefs_key = GetPrefsKey(kPrefsTotalBytesDownloaded, source);
  prefs_->SetInt64(prefs_key, total_bytes_downloaded);
  LOG_IF(INFO, log) << "Total bytes downloaded for "
                    << utils::ToString(source) << " = "
                    << GetTotalBytesDownloaded(source);
}

void PayloadState::LoadNumResponsesSeen() {
  SetNumResponsesSeen(GetPersistedValue(kPrefsNumResponsesSeen));
}

void PayloadState::SetNumResponsesSeen(int num_responses_seen) {
  CHECK(prefs_);
  num_responses_seen_ = num_responses_seen;
  LOG(INFO) << "Num Responses Seen = " << num_responses_seen_;
  prefs_->SetInt64(kPrefsNumResponsesSeen, num_responses_seen_);
}

void PayloadState::ReportUpdatesAbandonedEventCountMetric() {
  string metric = "Installer.UpdatesAbandonedEventCount";
  int value = num_responses_seen_ - 1;

  // Do not send an "abandoned" event when 0 payloads were abandoned since the
  // last successful update.
  if (value == 0)
    return;

  LOG(INFO) << "Uploading " << value << " (count) for metric " <<  metric;
  system_state_->metrics_lib()->SendToUMA(
       metric,
       value,
       0,    // min value
       100,  // max value
       kNumDefaultUmaBuckets);
}

void PayloadState::ComputeCandidateUrls() {
  bool http_url_ok = true;

  if (system_state_->hardware()->IsOfficialBuild()) {
    const policy::DevicePolicy* policy = system_state_->device_policy();
    if (policy && policy->GetHttpDownloadsEnabled(&http_url_ok) && !http_url_ok)
      LOG(INFO) << "Downloads via HTTP Url are not enabled by device policy";
  } else {
    LOG(INFO) << "Allowing HTTP downloads for unofficial builds";
    http_url_ok = true;
  }

  candidate_urls_.clear();
  for (size_t i = 0; i < response_.payload_urls.size(); i++) {
    string candidate_url = response_.payload_urls[i];
    if (StartsWithASCII(candidate_url, "http://", false) && !http_url_ok)
        continue;
    candidate_urls_.push_back(candidate_url);
    LOG(INFO) << "Candidate Url" << (candidate_urls_.size() - 1)
              << ": " << candidate_url;
  }

  LOG(INFO) << "Found " << candidate_urls_.size() << " candidate URLs "
            << "out of " << response_.payload_urls.size() << " URLs supplied";
}

void PayloadState::CreateSystemUpdatedMarkerFile() {
  CHECK(prefs_);
  int64_t value = system_state_->clock()->GetWallclockTime().ToInternalValue();
  prefs_->SetInt64(kPrefsSystemUpdatedMarker, value);
}

void PayloadState::BootedIntoUpdate(TimeDelta time_to_reboot) {
  // Send |time_to_reboot| as a UMA stat.
  string metric = "Installer.TimeToRebootMinutes";
  system_state_->metrics_lib()->SendToUMA(metric,
                                          time_to_reboot.InMinutes(),
                                          0,         // min: 0 minute
                                          30*24*60,  // max: 1 month (approx)
                                          kNumDefaultUmaBuckets);
  LOG(INFO) << "Uploading " << utils::FormatTimeDelta(time_to_reboot)
            << " for metric " <<  metric;

  metric = metrics::kMetricTimeToRebootMinutes;
  system_state_->metrics_lib()->SendToUMA(metric,
                                          time_to_reboot.InMinutes(),
                                          0,         // min: 0 minute
                                          30*24*60,  // max: 1 month (approx)
                                          kNumDefaultUmaBuckets);
  LOG(INFO) << "Uploading " << utils::FormatTimeDelta(time_to_reboot)
            << " for metric " <<  metric;
}

void PayloadState::UpdateEngineStarted() {
  // Flush previous state from abnormal attempt failure, if any.
  ReportAndClearPersistedAttemptMetrics();

  // Avoid the UpdateEngineStarted actions if this is not the first time we
  // run the update engine since reboot.
  if (!system_state_->system_rebooted())
    return;

  // Figure out if we just booted into a new update
  if (prefs_->Exists(kPrefsSystemUpdatedMarker)) {
    int64_t stored_value;
    if (prefs_->GetInt64(kPrefsSystemUpdatedMarker, &stored_value)) {
      Time system_updated_at = Time::FromInternalValue(stored_value);
      if (!system_updated_at.is_null()) {
        TimeDelta time_to_reboot =
            system_state_->clock()->GetWallclockTime() - system_updated_at;
        if (time_to_reboot.ToInternalValue() < 0) {
          LOG(ERROR) << "time_to_reboot is negative - system_updated_at: "
                     << utils::ToString(system_updated_at);
        } else {
          BootedIntoUpdate(time_to_reboot);
        }
      }
    }
    prefs_->Delete(kPrefsSystemUpdatedMarker);
  }
  // Check if it is needed to send metrics about a failed reboot into a new
  // version.
  ReportFailedBootIfNeeded();
}

void PayloadState::ReportFailedBootIfNeeded() {
  // If the kPrefsTargetVersionInstalledFrom is present, a successfully applied
  // payload was marked as ready immediately before the last reboot, and we
  // need to check if such payload successfully rebooted or not.
  if (prefs_->Exists(kPrefsTargetVersionInstalledFrom)) {
    int64_t installed_from = 0;
    if (!prefs_->GetInt64(kPrefsTargetVersionInstalledFrom, &installed_from)) {
      LOG(ERROR) << "Error reading TargetVersionInstalledFrom on reboot.";
      return;
    }
    if (static_cast<int>(installed_from) ==
        utils::GetPartitionNumber(system_state_->hardware()->BootDevice())) {
      // A reboot was pending, but the chromebook is again in the same
      // BootDevice where the update was installed from.
      int64_t target_attempt;
      if (!prefs_->GetInt64(kPrefsTargetVersionAttempt, &target_attempt)) {
        LOG(ERROR) << "Error reading TargetVersionAttempt when "
                      "TargetVersionInstalledFrom was present.";
        target_attempt = 1;
      }

      // Report the UMA metric of the current boot failure.
      string metric = "Installer.RebootToNewPartitionAttempt";

      LOG(INFO) << "Uploading " << target_attempt
                << " (count) for metric " <<  metric;
      system_state_->metrics_lib()->SendToUMA(
           metric,
           target_attempt,
           1,    // min value
           50,   // max value
           kNumDefaultUmaBuckets);

      metric = metrics::kMetricFailedUpdateCount;
      LOG(INFO) << "Uploading " << target_attempt
                << " (count) for metric " <<  metric;
      system_state_->metrics_lib()->SendToUMA(
           metric,
           target_attempt,
           1,    // min value
           50,   // max value
           kNumDefaultUmaBuckets);
    } else {
      prefs_->Delete(kPrefsTargetVersionAttempt);
      prefs_->Delete(kPrefsTargetVersionUniqueId);
    }
    prefs_->Delete(kPrefsTargetVersionInstalledFrom);
  }
}

void PayloadState::ExpectRebootInNewVersion(const string& target_version_uid) {
  // Expect to boot into the new partition in the next reboot setting the
  // TargetVersion* flags in the Prefs.
  string stored_target_version_uid;
  string target_version_id;
  string target_partition;
  int64_t target_attempt;

  if (prefs_->Exists(kPrefsTargetVersionUniqueId) &&
      prefs_->GetString(kPrefsTargetVersionUniqueId,
                        &stored_target_version_uid) &&
      stored_target_version_uid == target_version_uid) {
    if (!prefs_->GetInt64(kPrefsTargetVersionAttempt, &target_attempt))
      target_attempt = 0;
  } else {
    prefs_->SetString(kPrefsTargetVersionUniqueId, target_version_uid);
    target_attempt = 0;
  }
  prefs_->SetInt64(kPrefsTargetVersionAttempt, target_attempt + 1);

  prefs_->SetInt64(kPrefsTargetVersionInstalledFrom,
                    utils::GetPartitionNumber(
                        system_state_->hardware()->BootDevice()));
}

void PayloadState::ResetUpdateStatus() {
  // Remove the TargetVersionInstalledFrom pref so that if the machine is
  // rebooted the next boot is not flagged as failed to rebooted into the
  // new applied payload.
  prefs_->Delete(kPrefsTargetVersionInstalledFrom);

  // Also decrement the attempt number if it exists.
  int64_t target_attempt;
  if (prefs_->GetInt64(kPrefsTargetVersionAttempt, &target_attempt))
    prefs_->SetInt64(kPrefsTargetVersionAttempt, target_attempt-1);
}

int PayloadState::GetP2PNumAttempts() {
  return p2p_num_attempts_;
}

void PayloadState::SetP2PNumAttempts(int value) {
  p2p_num_attempts_ = value;
  LOG(INFO) << "p2p Num Attempts = " << p2p_num_attempts_;
  CHECK(prefs_);
  prefs_->SetInt64(kPrefsP2PNumAttempts, value);
}

void PayloadState::LoadP2PNumAttempts() {
  SetP2PNumAttempts(GetPersistedValue(kPrefsP2PNumAttempts));
}

Time PayloadState::GetP2PFirstAttemptTimestamp() {
  return p2p_first_attempt_timestamp_;
}

void PayloadState::SetP2PFirstAttemptTimestamp(const Time& time) {
  p2p_first_attempt_timestamp_ = time;
  LOG(INFO) << "p2p First Attempt Timestamp = "
            << utils::ToString(p2p_first_attempt_timestamp_);
  CHECK(prefs_);
  int64_t stored_value = time.ToInternalValue();
  prefs_->SetInt64(kPrefsP2PFirstAttemptTimestamp, stored_value);
}

void PayloadState::LoadP2PFirstAttemptTimestamp() {
  int64_t stored_value = GetPersistedValue(kPrefsP2PFirstAttemptTimestamp);
  Time stored_time = Time::FromInternalValue(stored_value);
  SetP2PFirstAttemptTimestamp(stored_time);
}

void PayloadState::P2PNewAttempt() {
  CHECK(prefs_);
  // Set timestamp, if it hasn't been set already
  if (p2p_first_attempt_timestamp_.is_null()) {
    SetP2PFirstAttemptTimestamp(system_state_->clock()->GetWallclockTime());
  }
  // Increase number of attempts
  SetP2PNumAttempts(GetP2PNumAttempts() + 1);
}

bool PayloadState::P2PAttemptAllowed() {
  if (p2p_num_attempts_ > kMaxP2PAttempts) {
    LOG(INFO) << "Number of p2p attempts is " << p2p_num_attempts_
              << " which is greater than "
              << kMaxP2PAttempts
              << " - disallowing p2p.";
    return false;
  }

  if (!p2p_first_attempt_timestamp_.is_null()) {
    Time now = system_state_->clock()->GetWallclockTime();
    TimeDelta time_spent_attempting_p2p = now - p2p_first_attempt_timestamp_;
    if (time_spent_attempting_p2p.InSeconds() < 0) {
      LOG(ERROR) << "Time spent attempting p2p is negative"
                 << " - disallowing p2p.";
      return false;
    }
    if (time_spent_attempting_p2p.InSeconds() > kMaxP2PAttemptTimeSeconds) {
      LOG(INFO) << "Time spent attempting p2p is "
                << utils::FormatTimeDelta(time_spent_attempting_p2p)
                << " which is greater than "
                << utils::FormatTimeDelta(TimeDelta::FromSeconds(
                       kMaxP2PAttemptTimeSeconds))
                << " - disallowing p2p.";
      return false;
    }
  }

  return true;
}

}  // namespace chromeos_update_engine
