// Copyright 2014 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 "metrics/uploader/system_profile_cache.h"

#include <string>
#include <vector>

#include "base/files/file_util.h"
#include "base/guid.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/sys_info.h"
#include "metrics/persistent_integer.h"
#include "metrics/uploader/metrics_log_base.h"
#include "metrics/uploader/proto/chrome_user_metrics_extension.pb.h"
#include "vboot/crossystem.h"

namespace {

const char kPersistentGUIDFile[] = "/var/lib/metrics/Sysinfo.GUID";
const char kPersistentSessionIdFilename[] = "Sysinfo.SessionId";
const char kProductIdFieldName[] = "GOOGLE_METRICS_PRODUCT_ID";

}  // namespace

std::string ChannelToString(
    const metrics::SystemProfileProto_Channel& channel) {
  switch (channel) {
    case metrics::SystemProfileProto::CHANNEL_STABLE:
    return "STABLE";
  case metrics::SystemProfileProto::CHANNEL_DEV:
    return "DEV";
  case metrics::SystemProfileProto::CHANNEL_BETA:
    return "BETA";
  case metrics::SystemProfileProto::CHANNEL_CANARY:
    return "CANARY";
  default:
    return "UNKNOWN";
  }
}

SystemProfileCache::SystemProfileCache()
    : initialized_(false),
    testing_(false),
    config_root_("/"),
    session_id_(new chromeos_metrics::PersistentInteger(
        kPersistentSessionIdFilename)) {
}

SystemProfileCache::SystemProfileCache(bool testing,
                                       const std::string& config_root)
    : initialized_(false),
      testing_(testing),
      config_root_(config_root),
      session_id_(new chromeos_metrics::PersistentInteger(
          kPersistentSessionIdFilename)) {
}

bool SystemProfileCache::Initialize() {
  CHECK(!initialized_)
      << "this should be called only once in the metrics_daemon lifetime.";

  std::string chromeos_version;
  std::string board;
  std::string build_type;
  if (!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_NAME",
                                         &profile_.os_name) ||
      !base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_VERSION",
                                         &profile_.os_version) ||
      !base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BOARD", &board) ||
      !base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BUILD_TYPE",
                                         &build_type) ||
      !GetChromeOSVersion(&chromeos_version) ||
      !GetHardwareId(&profile_.hardware_class)) {
    DLOG(ERROR) << "failing to initialize profile cache";
    return false;
  }

  std::string channel_string;
  base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_TRACK", &channel_string);
  profile_.channel = ProtoChannelFromString(channel_string);

  profile_.app_version = chromeos_version + " (" + build_type + ")" +
      ChannelToString(profile_.channel) + " " + board;

  // If the product id is not defined, use the default one from the protobuf.
  profile_.product_id = metrics::ChromeUserMetricsExtension::CHROME;
  if (GetProductId(&profile_.product_id)) {
    DLOG(INFO) << "Set the product id to " << profile_.product_id;
  }

  profile_.client_id =
      testing_ ? "client_id_test" : GetPersistentGUID(kPersistentGUIDFile);

  // Increment the session_id everytime we initialize this. If metrics_daemon
  // does not crash, this should correspond to the number of reboots of the
  // system.
  // TODO(bsimonnet): Change this to map to the number of time system-services
  // is started.
  session_id_->Add(1);
  profile_.session_id = static_cast<int32_t>(session_id_->Get());

  initialized_ = true;
  return initialized_;
}

bool SystemProfileCache::InitializeOrCheck() {
  return initialized_ || Initialize();
}

void SystemProfileCache::Populate(
    metrics::ChromeUserMetricsExtension* metrics_proto) {
  CHECK(metrics_proto);
  CHECK(InitializeOrCheck())
      << "failed to initialize system information.";

  // The client id is hashed before being sent.
  metrics_proto->set_client_id(
      metrics::MetricsLogBase::Hash(profile_.client_id));
  metrics_proto->set_session_id(profile_.session_id);

  // Sets the product id.
  metrics_proto->set_product(profile_.product_id);

  metrics::SystemProfileProto* profile_proto =
      metrics_proto->mutable_system_profile();
  profile_proto->mutable_hardware()->set_hardware_class(
      profile_.hardware_class);
  profile_proto->set_app_version(profile_.app_version);
  profile_proto->set_channel(profile_.channel);

  metrics::SystemProfileProto_OS* os = profile_proto->mutable_os();
  os->set_name(profile_.os_name);
  os->set_version(profile_.os_version);
}

std::string SystemProfileCache::GetPersistentGUID(const std::string& filename) {
  std::string guid;
  base::FilePath filepath(filename);
  if (!base::ReadFileToString(filepath, &guid)) {
    guid = base::GenerateGUID();
    // If we can't read or write the file, the guid will not be preserved during
    // the next reboot. Crash.
    CHECK(base::WriteFile(filepath, guid.c_str(), guid.size()));
  }
  return guid;
}

bool SystemProfileCache::GetChromeOSVersion(std::string* version) {
  if (testing_) {
    *version = "0.0.0.0";
    return true;
  }

  std::string milestone, build, branch, patch;
  unsigned tmp;
  if (base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_CHROME_MILESTONE",
                                        &milestone) &&
      base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BUILD_NUMBER",
                                        &build) &&
      base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BRANCH_NUMBER",
                                        &branch) &&
      base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_PATCH_NUMBER",
                                        &patch)) {
    // Convert to uint to ensure those fields are positive numbers.
    if (base::StringToUint(milestone, &tmp) &&
        base::StringToUint(build, &tmp) &&
        base::StringToUint(branch, &tmp) &&
        base::StringToUint(patch, &tmp)) {
      std::vector<std::string> parts = {milestone, build, branch, patch};
      *version = JoinString(parts, '.');
      return true;
    }
    DLOG(INFO) << "The milestone, build, branch or patch is not a positive "
               << "number.";
    return false;
  }
  DLOG(INFO) << "Field missing from /etc/lsb-release";
  return false;
}

bool SystemProfileCache::GetHardwareId(std::string* hwid) {
  CHECK(hwid);

  if (testing_) {
    // if we are in test mode, we do not call crossystem directly.
    DLOG(INFO) << "skipping hardware id";
    *hwid = "";
    return true;
  }

  char buffer[128];
  if (buffer != VbGetSystemPropertyString("hwid", buffer, sizeof(buffer))) {
    LOG(ERROR) << "error getting hwid";
    return false;
  }

  *hwid = std::string(buffer);
  return true;
}

bool SystemProfileCache::GetProductId(int* product_id) const {
  chromeos::OsReleaseReader reader;
  if (testing_) {
    base::FilePath root(config_root_);
    reader.LoadTestingOnly(root);
  } else {
    reader.Load();
  }

  std::string id;
  if (reader.GetString(kProductIdFieldName, &id)) {
    CHECK(base::StringToInt(id, product_id)) << "Failed to convert product_id "
                                             << id << " to int.";
    return true;
  }
  return false;
}

metrics::SystemProfileProto_Channel SystemProfileCache::ProtoChannelFromString(
    const std::string& channel) {

  if (channel == "stable-channel") {
    return metrics::SystemProfileProto::CHANNEL_STABLE;
  } else if (channel == "dev-channel") {
    return metrics::SystemProfileProto::CHANNEL_DEV;
  } else if (channel == "beta-channel") {
    return metrics::SystemProfileProto::CHANNEL_BETA;
  } else if (channel == "canary-channel") {
    return metrics::SystemProfileProto::CHANNEL_CANARY;
  }

  DLOG(INFO) << "unknown channel: " << channel;
  return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
}
