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

// Libary to provide access to the Chrome OS master configuration in YAML / JSON
// format

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

#include <string>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include "chromeos-config/libcros_config/cros_config.h"
#include "chromeos-config/libcros_config/identity.h"
#include "chromeos-config/libcros_config/identity_arm.h"
#include "chromeos-config/libcros_config/identity_x86.h"

namespace brillo {

constexpr char CrosConfigJson::kRootName[];
constexpr char CrosConfigJson::kConfigListName[];

CrosConfigJson::CrosConfigJson() : config_dict_(nullptr) {}

CrosConfigJson::~CrosConfigJson() {}

bool CrosConfigJson::SelectConfigByIdentityInternal(
    const CrosConfigIdentity& identity) {
  if (!json_config_.is_dict())
    return false;

  const base::Value* chromeos = json_config_.FindDictKey(kRootName);
  if (!chromeos)
    return false;

  const base::Value* configs_list = chromeos->FindListKey(kConfigListName);
  if (!configs_list)
    return false;

  const std::string& find_whitelabel_name = identity.GetVpdId();
  const int find_sku_id = identity.GetSkuId();

  for (size_t i = 0; i < configs_list->GetList().size(); ++i) {
    const base::Value& config_dict = configs_list->GetList()[i];
    if (!config_dict.is_dict())
      continue;

    const base::Value* identity_dict = config_dict.FindDictKey("identity");
    if (!identity_dict)
      continue;

    // Check SMBIOS name matches (x86) or dt-compatible (arm)
    if (!identity.PlatformIdentityMatch(*identity_dict))
      continue;

    // Check that either the SKU is less than zero, or the current
    // entry has a matching SKU id. If sku-id is not defined in the
    // identity dictionary, this entry will match any SKU id.
    if (find_sku_id != kDefaultSkuId) {
      base::Optional<int> current_sku_id = identity_dict->FindIntKey("sku-id");
      if (current_sku_id && current_sku_id != find_sku_id)
        continue;
    }

    // Currently, the find_whitelabel_name can be either the
    // whitelabel-tag or the customization-id.
    const std::string* current_vpd_tag =
        identity_dict->FindStringKey("whitelabel-tag");
    if (!current_vpd_tag)
      current_vpd_tag = identity_dict->FindStringKey("customization-id");
    if (!current_vpd_tag)
      current_vpd_tag = &base::EmptyString();
    if (*current_vpd_tag != find_whitelabel_name)
      continue;

    // SMBIOS name matches/dt-compatible, SKU matches, and VPD tag
    // matches. This is the config.
    config_dict_ = &config_dict;
    device_index_ = i;
    return true;
  }
  return false;
}

bool CrosConfigJson::SelectConfigByIdentity(
    const CrosConfigIdentity& identity) {
  if (!SelectConfigByIdentityInternal(identity)) {
    CROS_CONFIG_LOG(ERROR) << "Failed to find config for "
                           << identity.DebugString();
    return false;
  }
  inited_ = true;
  return true;
}

bool CrosConfigJson::GetString(const std::string& path,
                               const std::string& property,
                               std::string* val_out) {
  if (!InitCheck()) {
    return false;
  }

  if (path.empty()) {
    LOG(ERROR) << "Path must be specified";
    return false;
  }

  if (path[0] != '/') {
    LOG(ERROR) << "Path must start with / specifying the root node";
    return false;
  }

  const base::Value* attr_dict = config_dict_;

  if (path.length() > 1) {
    std::string path_no_root = path.substr(1);
    for (const auto& path : base::SplitStringPiece(
             path_no_root, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
      attr_dict = attr_dict->FindDictKey(path);
      if (!attr_dict) {
        CROS_CONFIG_LOG(ERROR) << "Failed to find path: " << path;
        return false;
      }
    }
  }

  const base::Value* value = attr_dict->FindKey(property);
  if (!value)
    return false;
  switch (value->type()) {
    case base::Value::Type::STRING:
      val_out->assign(value->GetString());
      return true;
    case base::Value::Type::INTEGER:
      val_out->assign(std::to_string(value->GetInt()));
      return true;
    case base::Value::Type::BOOLEAN:
      val_out->assign(value->GetBool() ? "true" : "false");
      return true;
    default:
      return false;
  }
}

bool CrosConfigJson::GetDeviceIndex(int* device_index_out) {
  if (!InitCheck()) {
    return false;
  }
  *device_index_out = device_index_;
  return true;
}

bool CrosConfigJson::ReadConfigFile(const base::FilePath& filepath) {
  std::string json_data;
  if (!base::ReadFileToString(filepath, &json_data)) {
    CROS_CONFIG_LOG(ERROR) << "Could not read file " << filepath.MaybeAsASCII();
    return false;
  }
  auto json_root = base::JSONReader::ReadAndReturnValueWithError(
      json_data, base::JSON_PARSE_RFC);
  if (!json_root.value) {
    CROS_CONFIG_LOG(ERROR) << "Fail to parse config.json: "
                           << json_root.error_message;
    return false;
  }
  json_config_ = std::move(json_root.value.value());

  return true;
}

}  // namespace brillo
