// 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 <iostream>
#include <sstream>
#include <string>
#include <vector>

#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/process/launch.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_util.h>
#include <base/strings/string_split.h>
#include <base/values.h>

namespace brillo {

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

CrosConfigJson::~CrosConfigJson() {}

bool CrosConfigJson::SelectConfigByIdentity(
    const CrosConfigIdentityArm* identity_arm,
    const CrosConfigIdentityX86* identity_x86) {
  const CrosConfigIdentity* identity;
  if (identity_arm) {
    identity = identity_arm;
  } else {
    identity = identity_x86;
  }
  const std::string& find_whitelabel_name = identity->GetVpdId();

  const base::DictionaryValue* root_dict = nullptr;
  if (json_config_->GetAsDictionary(&root_dict)) {
    const base::DictionaryValue* chromeos = nullptr;
    if (root_dict->GetDictionary("chromeos", &chromeos)) {
      const base::ListValue* configs_list = nullptr;
      if (chromeos->GetList("configs", &configs_list)) {
        size_t num_configs = configs_list->GetSize();
        for (size_t i = 0; i < num_configs; ++i) {
          const base::DictionaryValue* config_dict = nullptr;
          if (configs_list->GetDictionary(i, &config_dict)) {
            const base::DictionaryValue* identity_dict = nullptr;
            if (config_dict->GetDictionary("identity", &identity_dict)) {
              int find_sku_id = -1;
              bool platform_specific_match = false;
              if (identity_x86) {
                find_sku_id = identity_x86->GetSkuId();

                const std::string& find_name = identity_x86->GetName();
                std::string current_name;
                if (identity_dict->GetString("smbios-name-match",
                                             &current_name)) {
                  platform_specific_match = current_name == find_name;
                }
              } else if (identity_arm) {
                find_sku_id = identity_arm->GetSkuId();

                std::string current_dt_compatible_match;
                if (identity_dict->GetString("device-tree-compatible-match",
                                             &current_dt_compatible_match)) {
                  platform_specific_match =
                      identity_arm->IsCompatible(current_dt_compatible_match);
                }
              }
              bool sku_match = true;
              int current_sku_id;
              if (find_sku_id > -1 &&
                  identity_dict->GetInteger("sku-id", &current_sku_id)) {
                sku_match = current_sku_id == find_sku_id;
              }

              std::string current_vpd_tag = "";
              identity_dict->GetString("whitelabel-tag", &current_vpd_tag);
              if (current_vpd_tag.empty()) {
                identity_dict->GetString("customization-id", &current_vpd_tag);
              }
              // Currently, the find_whitelabel_name can be either the
              // whitelabel-tag or the customization-id.
              bool vpd_tag_match = current_vpd_tag == find_whitelabel_name;

              if (platform_specific_match && sku_match && vpd_tag_match) {
                config_dict_ = config_dict;
                break;
              }
            }
          }
        }
      }
    }
  }
  if (!config_dict_) {
    if (identity_arm) {
      CROS_CONFIG_LOG(ERROR)
          << "Failed to find config for device-tree compatible string: "
          << identity_arm->GetCompatibleDeviceString();
    } else {
      CROS_CONFIG_LOG(ERROR)
          << "Failed to find config for name: " << identity_x86->GetName()
          << " sku_id: " << identity_x86->GetSkuId()
          << " customization_id: " << find_whitelabel_name;
    }
    return false;
  }
  inited_ = true;
  return true;
}

bool CrosConfigJson::SelectConfigByIdentityArm(
    const CrosConfigIdentityArm& identity) {
  return SelectConfigByIdentity(&identity, NULL);
}
bool CrosConfigJson::SelectConfigByIdentityX86(
    const CrosConfigIdentityX86& identity) {
  return SelectConfigByIdentity(NULL, &identity);
}

bool CrosConfigJson::GetString(const std::string& path,
                               const std::string& prop,
                               std::string* val_out,
                               std::vector<std::string>* log_msgs_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;
  }

  bool valid_path = true;
  const base::DictionaryValue* attr_dict = config_dict_;

  if (path.length() > 1) {
    std::vector<std::string> path_tokens = base::SplitString(
        path.substr(1), "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    for (const std::string& path : path_tokens) {
      valid_path = attr_dict->GetDictionary(path, &attr_dict);
      if (!valid_path) {
        CROS_CONFIG_LOG(ERROR) << "Failed to find path: " << path;
        break;
      }
    }
  }

  if (valid_path) {
    std::string value;
    if (attr_dict->GetString(prop, &value)) {
      val_out->assign(value);
      return true;
    }

    int int_value;
    if (attr_dict->GetInteger(prop, &int_value)) {
      val_out->assign(std::to_string(int_value));
      return true;
    }

    bool bool_value;
    if (attr_dict->GetBoolean(prop, &bool_value)) {
      if (bool_value) {
        val_out->assign("true");
      } else {
        val_out->assign("false");
      }
      return true;
    }
  }
  return false;
}

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;
  }
  std::string error_msg;
  json_config_ = base::JSONReader::ReadAndReturnError(
      json_data, base::JSON_PARSE_RFC, nullptr /* error_code_out */, &error_msg,
      nullptr /* error_line_out */, nullptr /* error_column_out */);
  if (!json_config_) {
    CROS_CONFIG_LOG(ERROR) << "Fail to parse config.json: " << error_msg;
    return false;
  }

  return true;
}

}  // namespace brillo
