// Copyright (c) 2013 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/install_plan.h"

#include "base/logging.h"

#include "update_engine/utils.h"

using std::string;

namespace chromeos_update_engine {

InstallPlan::InstallPlan(bool is_resume,
                         bool is_full_update,
                         const string& url,
                         uint64_t payload_size,
                         const string& payload_hash,
                         uint64_t metadata_size,
                         const string& metadata_signature,
                         const string& install_path,
                         const string& kernel_install_path,
                         const std::string& public_key_rsa)
    : is_resume(is_resume),
      is_full_update(is_full_update),
      download_url(url),
      payload_size(payload_size),
      payload_hash(payload_hash),
      metadata_size(metadata_size),
      metadata_signature(metadata_signature),
      install_path(install_path),
      kernel_install_path(kernel_install_path),
      kernel_size(0),
      rootfs_size(0),
      hash_checks_mandatory(false),
      powerwash_required(false),
      public_key_rsa(public_key_rsa) {}

InstallPlan::InstallPlan() : is_resume(false),
                             is_full_update(false),  // play it safe.
                             payload_size(0),
                             metadata_size(0),
                             kernel_size(0),
                             rootfs_size(0),
                             hash_checks_mandatory(false),
                             powerwash_required(false) {}


bool InstallPlan::operator==(const InstallPlan& that) const {
  return ((is_resume == that.is_resume) &&
          (is_full_update == that.is_full_update) &&
          (download_url == that.download_url) &&
          (payload_size == that.payload_size) &&
          (payload_hash == that.payload_hash) &&
          (metadata_size == that.metadata_size) &&
          (metadata_signature == that.metadata_signature) &&
          (install_path == that.install_path) &&
          (kernel_install_path == that.kernel_install_path));
}

bool InstallPlan::operator!=(const InstallPlan& that) const {
  return !((*this) == that);
}

void InstallPlan::Dump() const {
  LOG(INFO) << "InstallPlan: "
            << (is_resume ? "resume" : "new_update")
            << ", payload type: " << (is_full_update ? "full" : "delta")
            << ", url: " << download_url
            << ", payload size: " << payload_size
            << ", payload hash: " << payload_hash
            << ", metadata size: " << metadata_size
            << ", metadata signature: " << metadata_signature
            << ", install_path: " << install_path
            << ", kernel_install_path: " << kernel_install_path
            << ", hash_checks_mandatory: " << utils::ToString(
                hash_checks_mandatory)
            << ", powerwash_required: " << utils::ToString(
                powerwash_required);
}

}  // namespace chromeos_update_engine
