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

// Library to provide access to the Chrome OS master configuration

#include "chromeos-config/libcros_config/cros_config.h"
#include "chromeos-config/libcros_config/cros_config_json.h"
#include "chromeos-config/libcros_config/identity_x86.h"

#include <stdlib.h>

#include <iostream>
#include <sstream>
#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/sys_info.h>

namespace {
const char kCustomizationId[] = "/sys/firmware/vpd/ro/customization_id";
const char kWhitelabelTag[] = "/sys/firmware/vpd/ro/whitelabel_tag";
const char kProductName[] = "/sys/devices/virtual/dmi/id/product_name";
const char kProductSku[] = "/sys/devices/virtual/dmi/id/product_sku";
const char kArmSkuId[] = "/proc/device-tree/firmware/coreboot/sku-id";
const char kDeviceTreeCompatiblePath[] = "/proc/device-tree/compatible";
const char kConfigJsonPath[] = "/usr/share/chromeos-config/config.json";
}  // namespace

namespace brillo {

CrosConfig::CrosConfig() {}

CrosConfig::~CrosConfig() {}

bool CrosConfig::InitCheck() const {
  if (!cros_config_) {
    CROS_CONFIG_LOG(ERROR)
        << "Init*() must be called before accessing configuration";
    return false;
  }
  return true;
}

bool CrosConfig::Init(const int sku_id) {
  return InitModel(sku_id);
}

bool CrosConfig::Init() {
  return InitModel();
}

bool CrosConfig::InitForTestX86(const base::FilePath& filepath,
                                const std::string& name,
                                int sku_id,
                                const std::string& customization_id) {
  base::FilePath product_name_file, product_sku_file, vpd_file;
  CrosConfigIdentityX86 identity;
  if (!identity.FakeVpd(customization_id, &vpd_file)) {
    CROS_CONFIG_LOG(ERROR) << "FakeVpd() failed";
    return false;
  }
  if (!identity.Fake(name, sku_id, &product_name_file, &product_sku_file)) {
    CROS_CONFIG_LOG(ERROR) << "FakeVpd() failed";
    return false;
  }
  return InitCrosConfig(filepath) &&
         SelectConfigByIdentityX86(product_name_file, product_sku_file,
                                   vpd_file);
}

bool CrosConfig::InitForTestArm(const base::FilePath& filepath,
                                const std::string& dt_compatible_name,
                                int sku_id,
                                const std::string& customization_id) {
  base::FilePath dt_compatible_file, sku_id_file, vpd_file;
  CrosConfigIdentityArm identity;
  if (!identity.FakeVpd(customization_id, &vpd_file)) {
    CROS_CONFIG_LOG(ERROR) << "FakeVpd() failed";
    return false;
  }
  if (!identity.Fake(dt_compatible_name, sku_id, &dt_compatible_file,
                     &sku_id_file)) {
    CROS_CONFIG_LOG(ERROR) << "FakeDtCompatible() failed";
    return false;
  }
  return InitCrosConfig(filepath) &&
         SelectConfigByIdentityArm(dt_compatible_file,
                                   sku_id_file, vpd_file);
}

bool CrosConfig::InitModel() {
  return InitModel(kDefaultSkuId);
}

bool CrosConfig::InitModel(const int sku_id) {
  base::FilePath json_path(kConfigJsonPath);
  bool init_config = false;
  if (base::PathExists(json_path)) {
    init_config = InitCrosConfig(json_path);
  }
  if (!init_config) {
    return false;
  }
  const std::string system_arch = base::SysInfo::OperatingSystemArchitecture();
  base::FilePath vpd_file(kWhitelabelTag);
  if (!base::PathExists(vpd_file)) {
    vpd_file = base::FilePath(kCustomizationId);
  }
  if (system_arch == "x86_64" || system_arch == "x86") {
    base::FilePath product_name_file(kProductName);
    base::FilePath product_sku_file(kProductSku);
    return SelectConfigByIdentityX86(product_name_file, product_sku_file,
                                     vpd_file, sku_id);
  } else {
    base::FilePath dt_compatible_file(kDeviceTreeCompatiblePath);
    base::FilePath sku_id_file(kArmSkuId);
    return SelectConfigByIdentityArm(dt_compatible_file, sku_id_file,
                                     vpd_file, sku_id);
  }
}

bool CrosConfig::GetString(const std::string& path,
                           const std::string& prop,
                           std::string* val_out,
                           std::vector<std::string>* log_msgs_out) {
  if (!InitCheck()) {
    return false;
  }
  return cros_config_->GetString(path, prop, val_out, log_msgs_out);
}

bool CrosConfig::GetString(const std::string& path,
                           const std::string& prop,
                           std::string* val_out) {
  if (!InitCheck()) {
    return false;
  }
  return cros_config_->GetString(path, prop, val_out);
}

bool CrosConfig::SelectConfigByIdentityX86(
    const base::FilePath& product_name_file,
    const base::FilePath& product_sku_file,
    const base::FilePath& vpd_file,
    const int sku_id) {
  CROS_CONFIG_LOG(INFO) << ">>>>> Starting to read X86 identity";
  CrosConfigIdentityX86 identity;
  if (!identity.ReadVpd(vpd_file)) {
    CROS_CONFIG_LOG(ERROR) << "Cannot read VPD identity";
    return false;
  }
  if (!identity.ReadInfo(product_name_file, product_sku_file)) {
    CROS_CONFIG_LOG(ERROR) << "Cannot read SMBIOS identity";
    return false;
  }
  if (sku_id != kDefaultSkuId) {
    identity.SetSkuId(sku_id);
    CROS_CONFIG_LOG(INFO) << "Set sku_id to explicitly assigned value "
                          << sku_id;
  }
  if (!cros_config_->SelectConfigByIdentityX86(identity)) {
    CROS_CONFIG_LOG(ERROR) << "Cannot find config for"
                           << " name: " << identity.GetName()
                           << " SKU ID: " << identity.GetSkuId()
                           << " VPD ID from " << vpd_file.MaybeAsASCII() << ": "
                           << identity.GetVpdId();
    return false;
  }

  CROS_CONFIG_LOG(INFO) << ">>>>> Completed initialization with x86 identity";

  return true;
}

bool CrosConfig::SelectConfigByIdentityArm(
    const base::FilePath& dt_compatible_file,
    const base::FilePath& sku_id_file,
    const base::FilePath& vpd_file,
    const int sku_id) {
  CROS_CONFIG_LOG(INFO) << ">>>>> Starting to read ARM identity";
  CrosConfigIdentityArm identity;
  if (!identity.ReadVpd(vpd_file)) {
    CROS_CONFIG_LOG(ERROR) << "Cannot read VPD identity";
    return false;
  }
  if (!identity.ReadInfo(dt_compatible_file, sku_id_file)) {
    CROS_CONFIG_LOG(ERROR) << "Cannot read device-tree compatible and "
                           << "sku-id identities";
    return false;
  }
  if (sku_id != kDefaultSkuId) {
    identity.SetSkuId(sku_id);
    CROS_CONFIG_LOG(INFO) << "Set sku_id to explicitly assigned value "
                          << sku_id;
  }
  if (!cros_config_->SelectConfigByIdentityArm(identity)) {
    CROS_CONFIG_LOG(ERROR) << "Cannot find config for "
                           << "device-tree compatible string: "
                           << identity.GetCompatibleDeviceString()
                           << " SKU ID: " << identity.GetSkuId()
                           << " VPD ID from " << vpd_file.MaybeAsASCII()
                           << ": " << identity.GetVpdId();
    return false;
  }

  CROS_CONFIG_LOG(INFO) << ">>>>> Completed initialization with ARM identity";

  return true;
}

bool CrosConfig::InitCrosConfig(const base::FilePath& filepath) {
  CROS_CONFIG_LOG(INFO) << ">>>>> reading config file: path="
                        << filepath.MaybeAsASCII();
  // Many systems will not have a config database (yet), so just skip all the
  // setup without any errors if the config file doesn't exist.
  if (!base::PathExists(filepath)) {
    return false;
  }

  cros_config_ = std::make_unique<CrosConfigJson>();

  cros_config_->ReadConfigFile(filepath);

  CROS_CONFIG_LOG(INFO) << ">>>>> config file successfully read";

  return true;
}

}  // namespace brillo
