// Copyright 2018 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 "arc/setup/config.h"

#include <utility>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>

namespace arc {

namespace {

// Performs a best-effort conversion of the input string to a boolean type,
// setting |*out| to the result of the conversion.  Returns true for successful
// conversions.
bool StringToBool(const std::string str, bool* out) {
  if (str == "0" || base::EqualsCaseInsensitiveASCII(str, "false")) {
    *out = false;
    return true;
  }
  if (str == "1" || base::EqualsCaseInsensitiveASCII(str, "true")) {
    *out = true;
    return true;
  }
  return false;
}

}  // namespace

Config::Config(const base::FilePath& config_json,
               std::unique_ptr<base::Environment> config_env)
    : env_(std::move(config_env)) {
  if (!config_json.empty())
    CHECK(ParseJsonFile(config_json));
}

Config::~Config() = default;

bool Config::GetString(base::StringPiece name, std::string* out) const {
  base::Value* config = FindConfig(name);
  return config ? config->GetAsString(out)
                : env_->GetVar(name.as_string().c_str(), out);
}

bool Config::GetInt(base::StringPiece name, int* out) const {
  base::Value* config = FindConfig(name);
  if (config)
    return config->GetAsInteger(out);
  std::string env_str;
  return env_->GetVar(name.as_string().c_str(), &env_str) &&
         base::StringToInt(env_str, out);
}

bool Config::GetBool(base::StringPiece name, bool* out) const {
  base::Value* config = FindConfig(name);
  if (config)
    return config->GetAsBoolean(out);
  std::string env_str;
  return env_->GetVar(name.as_string().c_str(), &env_str) &&
         StringToBool(env_str, out);
}

std::string Config::GetStringOrDie(base::StringPiece name) const {
  std::string ret;
  CHECK(GetString(name, &ret)) << name;
  return ret;
}

int Config::GetIntOrDie(base::StringPiece name) const {
  int ret;
  CHECK(GetInt(name, &ret)) << name;
  return ret;
}

bool Config::GetBoolOrDie(base::StringPiece name) const {
  bool ret;
  CHECK(GetBool(name, &ret)) << name;
  return ret;
}

bool Config::ParseJsonFile(const base::FilePath& config_json) {
  std::string json_str;
  if (!base::ReadFileToString(config_json, &json_str)) {
    PLOG(ERROR) << "Failed to read json string from " << config_json.value();
    return false;
  }

  auto result = base::JSONReader::ReadAndReturnValueWithError(
      json_str, base::JSON_PARSE_RFC);
  if (!result.value) {
    LOG(ERROR) << "Failed to parse json: " << result.error_message;
    return false;
  }

  if (!result.value->is_dict()) {
    LOG(ERROR) << "Failed to read json as dictionary";
    return false;
  }

  for (const auto& item : result.value->DictItems()) {
    if (!json_
             .emplace(item.first,
                      base::Value::ToUniquePtrValue(std::move(item.second)))
             .second) {
      LOG(ERROR) << "The config " << item.first
                 << " appeared twice in the file.";
      return false;
    }
  }
  return true;
}

base::Value* Config::FindConfig(base::StringPiece name) const {
  auto it = json_.find(name.as_string());
  if (it == json_.end())
    return nullptr;
  return it->second.get();
}

}  // namespace arc
