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

#include <base/check.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;
}
