// 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 <optional>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/hash/sha1.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/system/sys_info.h>
#include <chromeos-config/libcros_config/cros_config.h>
#include <vboot/crossystem.h>

#include "runtime_probe/probe_config_loader_impl.h"
#include "runtime_probe/system_property_impl.h"

namespace runtime_probe {

namespace {

constexpr char kUsrLocal[] = "usr/local";

std::string GetProbeConfigSHA1Hash(const std::string& content) {
  const auto& hash_val = base::SHA1HashString(content);
  return base::HexEncode(hash_val.data(), hash_val.size());
}

std::optional<ProbeConfigData> LoadProbeConfig(
    const base::FilePath& file_path) {
  DVLOG(2) << "LoadProbeConfig: " << file_path;
  std::string config_json;
  if (!base::ReadFileToString(file_path, &config_json)) {
    DVLOG(2) << "Failed to read probe config";
    return std::nullopt;
  }
  const auto probe_config_sha1_hash = GetProbeConfigSHA1Hash(config_json);
  DVLOG(3) << "SHA1 hash of probe config: " << probe_config_sha1_hash;

  auto json_val = base::JSONReader::Read(config_json, base::JSON_PARSE_RFC);
  if (!json_val || !json_val->is_dict()) {
    DVLOG(2) << "Failed to parse probe config as JSON.";
    DVLOG(3) << "Input: " << config_json;
    return std::nullopt;
  }

  const auto absolute_path = base::MakeAbsoluteFilePath(file_path);
  return ProbeConfigData{.path = absolute_path,
                         .config = std::move(*json_val),
                         .sha1_hash = std::move(probe_config_sha1_hash)};
}

}  // namespace

ProbeConfigLoaderImpl::ProbeConfigLoaderImpl() : root_("/") {
  auto config = std::make_unique<brillo::CrosConfig>();
  if (config->Init()) {
    cros_config_ = std::move(config);
  }
  system_property_ = std::make_unique<SystemPropertyImpl>();
}

std::optional<ProbeConfigData> ProbeConfigLoaderImpl::LoadDefault() const {
  for (const auto& file_path : GetDefaultPaths()) {
    auto ret = LoadProbeConfig(file_path);
    if (ret) {
      DVLOG(1) << "Load default config from: " << file_path;
      return ret;
    }
  }
  DVLOG(1) << "Cannot find any default probe configs";
  return std::nullopt;
}

std::optional<ProbeConfigData> ProbeConfigLoaderImpl::LoadFromFile(
    const base::FilePath& file_path) const {
  if (GetCrosDebug() != 1) {
    LOG(ERROR) << "Arbitrary probe config is only allowed with cros_debug=1";
    return std::nullopt;
  }
  auto ret = LoadProbeConfig(file_path);
  DVLOG(1) << "Load config from: " << file_path;
  return ret;
}

std::vector<base::FilePath> ProbeConfigLoaderImpl::GetDefaultPaths() const {
  std::vector<base::FilePath> file_paths;
  std::string model_name = GetModelName();
  if (GetCrosDebug() == 1) {
    auto probe_config_dir =
        root_.Append(kUsrLocal).Append(kRuntimeProbeConfigDir);
    file_paths.push_back(
        probe_config_dir.Append(model_name).Append(kRuntimeProbeConfigName));
    file_paths.push_back(probe_config_dir.Append(kRuntimeProbeConfigName));
  }
  auto probe_config_dir = root_.Append(kRuntimeProbeConfigDir);
  file_paths.push_back(
      probe_config_dir.Append(model_name).Append(kRuntimeProbeConfigName));
  file_paths.push_back(probe_config_dir.Append(kRuntimeProbeConfigName));
  return file_paths;
}

void ProbeConfigLoaderImpl::SetCrosConfigForTesting(
    std::unique_ptr<brillo::CrosConfigInterface> cros_config) {
  cros_config_ = std::move(cros_config);
}

void ProbeConfigLoaderImpl::SetSystemProertyForTesting(
    std::unique_ptr<SystemProperty> system_property) {
  system_property_ = std::move(system_property);
}

void ProbeConfigLoaderImpl::SetRootForTest(const base::FilePath& root) {
  root_ = root;
}

int ProbeConfigLoaderImpl::GetCrosDebug() const {
  int cros_config;

  if (system_property_->GetInt("cros_debug", &cros_config))
    return cros_config;

  // Fallback to disabled cros_debug.
  return 0;
}

std::string ProbeConfigLoaderImpl::GetModelName() const {
  std::string model_name;

  if (cros_config_->GetString(kCrosConfigModelNamePath, kCrosConfigModelNameKey,
                              &model_name))
    return model_name;

  // Fallback to sys_info.
  return base::SysInfo::GetLsbReleaseBoard();
}

}  // namespace runtime_probe
