// 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/system/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[] =
    "/var/lib/metrics/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() : SystemProfileCache(false, "/") {}

SystemProfileCache::SystemProfileCache(bool testing,
                                       const std::string& config_root)
    : initialized_(false), testing_(testing), config_root_(config_root) {
  base::FilePath backing_file(kPersistentSessionIdFilename);
  session_id_.reset(new chromeos_metrics::PersistentInteger(backing_file));
}

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)) {
    DLOG(ERROR) << "failing to initialize profile cache";
    return false;
  }

  if (!GetHardwareId(&profile_.hardware_class)) {
    profile_.hardware_class.clear();
  }

  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 = base::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 {
  brillo::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;
}
