// Copyright 2021 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 "rmad/utils/cros_config_utils_impl.h"

#include <fstream>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <chromeos-config/libcros_config/cros_config.h>

#include "rmad/utils/json_store.h"

namespace rmad {

namespace {

// TODO(genechang): We should build the configuration ourselves to
// prevent possible changes to the configuration file in the future.
const std::string kChromeosConfigPath(
    "/usr/share/chromeos-config/yaml/config.yaml");

constexpr char kChromeos[] = "chromeos";
constexpr char kChromeosConfigs[] = "configs";

constexpr char kCrosRootKey[] = "/";
constexpr char kCrosModelNameKey[] = "name";
constexpr char kCrosIdentityKey[] = "identity";
constexpr char kCrosIdentitySkuKey[] = "sku-id";
constexpr char kCrosIdentityWhitelabelKey[] = "whitelabel-tag";

}  // namespace

CrosConfigUtilsImpl::CrosConfigUtilsImpl()
    : config_file_path_(kChromeosConfigPath) {
  cros_config_ = std::make_unique<brillo::CrosConfig>();
}

CrosConfigUtilsImpl::CrosConfigUtilsImpl(
    const std::string& config_file_path,
    std::unique_ptr<brillo::CrosConfigInterface> cros_config)
    : config_file_path_(config_file_path),
      cros_config_(std::move(cros_config)) {}

bool CrosConfigUtilsImpl::GetModelName(std::string* model_name) {
  DCHECK(model_name);

  return cros_config_->GetString(kCrosRootKey, kCrosModelNameKey, model_name);
}

bool CrosConfigUtilsImpl::GetCurrentSkuId(int* sku_id) {
  DCHECK(sku_id);

  std::string sku_id_str;
  if (!cros_config_->GetString(
          std::string(kCrosRootKey) + std::string(kCrosIdentityKey),
          kCrosIdentitySkuKey, &sku_id_str)) {
    return false;
  }

  return base::StringToInt(sku_id_str, sku_id);
}

bool CrosConfigUtilsImpl::GetCurrentWhitelabelTag(std::string* whitelabel_tag) {
  DCHECK(whitelabel_tag);

  return cros_config_->GetString(
      std::string(kCrosRootKey) + std::string(kCrosIdentityKey),
      kCrosIdentityWhitelabelKey, whitelabel_tag);
}

bool CrosConfigUtilsImpl::GetSkuIdList(std::vector<int>* sku_id_list) {
  DCHECK(sku_id_list);

  std::vector<base::Value> values;
  if (!GetMatchedItemsFromIdentity(kCrosIdentitySkuKey, &values)) {
    return false;
  }

  sku_id_list->clear();
  for (auto& value : values) {
    int sku;
    if (value.GetAsInteger(&sku)) {
      sku_id_list->push_back(sku);
    }
  }
  return true;
}

bool CrosConfigUtilsImpl::GetWhitelabelTagList(
    std::vector<std::string>* whitelabel_tag_list) {
  DCHECK(whitelabel_tag_list);

  std::vector<base::Value> values;
  if (!GetMatchedItemsFromIdentity(kCrosIdentityWhitelabelKey, &values)) {
    return false;
  }

  whitelabel_tag_list->clear();
  for (auto& value : values) {
    std::string tag;
    if (value.GetAsString(&tag)) {
      whitelabel_tag_list->push_back(tag);
    }
  }
  return true;
}

bool CrosConfigUtilsImpl::GetMatchedItemsFromIdentity(
    const std::string& key, std::vector<base::Value>* list) {
  DCHECK(list);

  list->clear();
  std::set<base::Value> items;

  std::string model_name;
  if (!GetModelName(&model_name)) {
    LOG(ERROR) << "Failed to get model name for comparison";
    return false;
  }

  scoped_refptr<JsonStore> json_store =
      base::MakeRefCounted<JsonStore>(base::FilePath(config_file_path_));

  if (auto error = json_store->GetReadError();
      error != JsonStore::READ_ERROR_NONE) {
    LOG_STREAM(ERROR) << "Failed to parse file due to error code #" << error;
    return false;
  }

  base::Value cros;
  if (!json_store->GetValue(kChromeos, &cros)) {
    LOG(ERROR) << "Failed to get the chromeos section from the file";
    return false;
  }
  DCHECK(cros.is_dict());

  base::Value* cros_configs = cros.FindListKey(kChromeosConfigs);
  if (!cros_configs) {
    LOG(ERROR) << "Failed to get the configs section from the file";
    return false;
  }

  DCHECK(cros_configs->is_list());
  auto list_configs = cros_configs->GetList();
  for (auto& config : list_configs) {
    DCHECK(config.is_dict());
    const std::string* name = config.FindStringKey(kCrosModelNameKey);
    if (!name || *name != model_name) {
      continue;
    }

    const base::Value* identity = config.FindKey(kCrosIdentityKey);
    DCHECK(identity->is_dict());
    const base::Value* item = identity->FindKey(key);
    if (item) {
      items.insert(item->Clone());
    }
  }

  for (auto& item : items) {
    list->push_back(item.Clone());
  }
  return true;
}

}  // namespace rmad
