/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "host/libs/config/cuttlefish_config.h"

#include <algorithm>
#include <climits>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iterator>
#include <sstream>
#include <string>
#include <time.h>

#include <android-base/strings.h>
#include <android-base/logging.h>
#include <json/json.h>

#include "common/libs/utils/environment.h"
#include "common/libs/utils/files.h"
#include "host/libs/vm_manager/crosvm_manager.h"
#include "host/libs/vm_manager/qemu_manager.h"

namespace cuttlefish {
namespace {

int InstanceFromEnvironment() {
  static constexpr char kInstanceEnvironmentVariable[] = "CUTTLEFISH_INSTANCE";
  static constexpr int kDefaultInstance = 1;

  // CUTTLEFISH_INSTANCE environment variable
  std::string instance_str = StringFromEnv(kInstanceEnvironmentVariable, "");
  if (instance_str.empty()) {
    // Try to get it from the user instead
    instance_str = StringFromEnv("USER", "");

    if (instance_str.empty()) {
      LOG(DEBUG) << "CUTTLEFISH_INSTANCE and USER unset, using instance id "
                 << kDefaultInstance;
      return kDefaultInstance;
    }
    if (!android::base::StartsWith(instance_str, kVsocUserPrefix)) {
      // No user or we don't recognize this user
      LOG(DEBUG) << "Non-vsoc user, using instance id " << kDefaultInstance;
      return kDefaultInstance;
    }
    instance_str = instance_str.substr(std::string(kVsocUserPrefix).size());
  }
  int instance = std::stoi(instance_str);
  if (instance <= 0) {
    LOG(INFO) << "Failed to interpret \"" << instance_str << "\" as an id, "
              << "using instance id " << kDefaultInstance;
    return kDefaultInstance;
  }
  return instance;
}

const char* kInstances = "instances";


}  // namespace

const char* const kGpuModeAuto = "auto";
const char* const kGpuModeGuestSwiftshader = "guest_swiftshader";
const char* const kGpuModeDrmVirgl = "drm_virgl";
const char* const kGpuModeGfxStream = "gfxstream";

std::string DefaultEnvironmentPath(const char* environment_key,
                                   const char* default_value,
                                   const char* subpath) {
  return StringFromEnv(environment_key, default_value) + "/" + subpath;
}

static constexpr char kAssemblyDir[] = "assembly_dir";
std::string CuttlefishConfig::assembly_dir() const {
  return (*dictionary_)[kAssemblyDir].asString();
}
void CuttlefishConfig::set_assembly_dir(const std::string& assembly_dir) {
  (*dictionary_)[kAssemblyDir] = assembly_dir;
}

static constexpr char kVmManager[] = "vm_manager";
std::string CuttlefishConfig::vm_manager() const {
  return (*dictionary_)[kVmManager].asString();
}
void CuttlefishConfig::set_vm_manager(const std::string& name) {
  (*dictionary_)[kVmManager] = name;
}

static constexpr char kGpuMode[] = "gpu_mode";
std::string CuttlefishConfig::gpu_mode() const {
  return (*dictionary_)[kGpuMode].asString();
}
void CuttlefishConfig::set_gpu_mode(const std::string& name) {
  (*dictionary_)[kGpuMode] = name;
}

static constexpr char kCpus[] = "cpus";
int CuttlefishConfig::cpus() const { return (*dictionary_)[kCpus].asInt(); }
void CuttlefishConfig::set_cpus(int cpus) { (*dictionary_)[kCpus] = cpus; }

static constexpr char kMemoryMb[] = "memory_mb";
int CuttlefishConfig::memory_mb() const {
  return (*dictionary_)[kMemoryMb].asInt();
}
void CuttlefishConfig::set_memory_mb(int memory_mb) {
  (*dictionary_)[kMemoryMb] = memory_mb;
}

static constexpr char kDisplayConfigs[] = "display_configs";
static constexpr char kXRes[] = "x_res";
static constexpr char kYRes[] = "y_res";
static constexpr char kDpi[] = "dpi";
static constexpr char kRefreshRateHz[] = "refresh_rate_hz";
std::vector<CuttlefishConfig::DisplayConfig>
CuttlefishConfig::display_configs() const {
  std::vector<DisplayConfig> display_configs;
  for (auto& display_config_json : (*dictionary_)[kDisplayConfigs]) {
    DisplayConfig display_config = {};
    display_config.width = display_config_json[kXRes].asInt();
    display_config.height = display_config_json[kYRes].asInt();
    display_config.dpi = display_config_json[kDpi].asInt();
    display_config.refresh_rate_hz =
        display_config_json[kRefreshRateHz].asInt();
    display_configs.emplace_back(std::move(display_config));
  }
  return display_configs;
}
void CuttlefishConfig::set_display_configs(
    const std::vector<DisplayConfig>& display_configs) {
  Json::Value display_configs_json(Json::arrayValue);

  for (const DisplayConfig& display_configs : display_configs) {
    Json::Value display_config_json(Json::objectValue);
    display_config_json[kXRes] = display_configs.width;
    display_config_json[kYRes] = display_configs.height;
    display_config_json[kDpi] = display_configs.dpi;
    display_config_json[kRefreshRateHz] = display_configs.refresh_rate_hz;
    display_configs_json.append(display_config_json);
  }

  (*dictionary_)[kDisplayConfigs] = display_configs_json;
}

void CuttlefishConfig::SetPath(const std::string& key,
                               const std::string& path) {
  if (!path.empty()) {
    (*dictionary_)[key] = AbsolutePath(path);
  }
}

static constexpr char kGdbPort[] = "gdb_port";
int CuttlefishConfig::gdb_port() const {
  return (*dictionary_)[kGdbPort].asInt();
}
void CuttlefishConfig::set_gdb_port(int port) {
  (*dictionary_)[kGdbPort] = port;
}

static constexpr char kDeprecatedBootCompleted[] = "deprecated_boot_completed";
bool CuttlefishConfig::deprecated_boot_completed() const {
  return (*dictionary_)[kDeprecatedBootCompleted].asBool();
}
void CuttlefishConfig::set_deprecated_boot_completed(
    bool deprecated_boot_completed) {
  (*dictionary_)[kDeprecatedBootCompleted] = deprecated_boot_completed;
}

static constexpr char kCuttlefishEnvPath[] = "cuttlefish_env_path";
void CuttlefishConfig::set_cuttlefish_env_path(const std::string& path) {
  SetPath(kCuttlefishEnvPath, path);
}
std::string CuttlefishConfig::cuttlefish_env_path() const {
  return (*dictionary_)[kCuttlefishEnvPath].asString();
}

static AdbMode stringToAdbMode(std::string mode) {
  std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
  if (mode == "vsock_tunnel") {
    return AdbMode::VsockTunnel;
  } else if (mode == "vsock_half_tunnel") {
    return AdbMode::VsockHalfTunnel;
  } else if (mode == "native_vsock") {
    return AdbMode::NativeVsock;
  } else {
    return AdbMode::Unknown;
  }
}

static constexpr char kAdbMode[] = "adb_mode";
std::set<AdbMode> CuttlefishConfig::adb_mode() const {
  std::set<AdbMode> args_set;
  for (auto& mode : (*dictionary_)[kAdbMode]) {
    args_set.insert(stringToAdbMode(mode.asString()));
  }
  return args_set;
}
void CuttlefishConfig::set_adb_mode(const std::set<std::string>& mode) {
  Json::Value mode_json_obj(Json::arrayValue);
  for (const auto& arg : mode) {
    mode_json_obj.append(arg);
  }
  (*dictionary_)[kAdbMode] = mode_json_obj;
}

static SecureHal StringToSecureHal(std::string mode) {
  std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
  if (mode == "keymint") {
    return SecureHal::Keymint;
  } else if (mode == "gatekeeper") {
    return SecureHal::Gatekeeper;
  } else {
    return SecureHal::Unknown;
  }
}

static constexpr char kSecureHals[] = "secure_hals";
std::set<SecureHal> CuttlefishConfig::secure_hals() const {
  std::set<SecureHal> args_set;
  for (auto& hal : (*dictionary_)[kSecureHals]) {
    args_set.insert(StringToSecureHal(hal.asString()));
  }
  return args_set;
}
void CuttlefishConfig::set_secure_hals(const std::set<std::string>& hals) {
  Json::Value hals_json_obj(Json::arrayValue);
  for (const auto& hal : hals) {
    hals_json_obj.append(hal);
  }
  (*dictionary_)[kSecureHals] = hals_json_obj;
}

static constexpr char kSetupWizardMode[] = "setupwizard_mode";
std::string CuttlefishConfig::setupwizard_mode() const {
  return (*dictionary_)[kSetupWizardMode].asString();
}
void CuttlefishConfig::set_setupwizard_mode(const std::string& mode) {
  (*dictionary_)[kSetupWizardMode] = mode;
}

static constexpr char kQemuBinaryDir[] = "qemu_binary_dir";
std::string CuttlefishConfig::qemu_binary_dir() const {
  return (*dictionary_)[kQemuBinaryDir].asString();
}
void CuttlefishConfig::set_qemu_binary_dir(const std::string& qemu_binary_dir) {
  (*dictionary_)[kQemuBinaryDir] = qemu_binary_dir;
}

static constexpr char kCrosvmBinary[] = "crosvm_binary";
std::string CuttlefishConfig::crosvm_binary() const {
  return (*dictionary_)[kCrosvmBinary].asString();
}
void CuttlefishConfig::set_crosvm_binary(const std::string& crosvm_binary) {
  (*dictionary_)[kCrosvmBinary] = crosvm_binary;
}

static constexpr char kTpmDevice[] = "tpm_device";
std::string CuttlefishConfig::tpm_device() const {
  return (*dictionary_)[kTpmDevice].asString();
}
void CuttlefishConfig::set_tpm_device(const std::string& tpm_device) {
  (*dictionary_)[kTpmDevice] = tpm_device;
}

static constexpr char kEnableGnssGrpcProxy[] = "enable_gnss_grpc_proxy";
void CuttlefishConfig::set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy) {
  (*dictionary_)[kEnableGnssGrpcProxy] = enable_gnss_grpc_proxy;
}
bool CuttlefishConfig::enable_gnss_grpc_proxy() const {
  return (*dictionary_)[kEnableGnssGrpcProxy].asBool();
}

static constexpr char kEnableVncServer[] = "enable_vnc_server";
bool CuttlefishConfig::enable_vnc_server() const {
  return (*dictionary_)[kEnableVncServer].asBool();
}
void CuttlefishConfig::set_enable_vnc_server(bool enable_vnc_server) {
  (*dictionary_)[kEnableVncServer] = enable_vnc_server;
}

static constexpr char kEnableSandbox[] = "enable_sandbox";
void CuttlefishConfig::set_enable_sandbox(const bool enable_sandbox) {
  (*dictionary_)[kEnableSandbox] = enable_sandbox;
}
bool CuttlefishConfig::enable_sandbox() const {
  return (*dictionary_)[kEnableSandbox].asBool();
}

static constexpr char kSeccompPolicyDir[] = "seccomp_policy_dir";
void CuttlefishConfig::set_seccomp_policy_dir(const std::string& seccomp_policy_dir) {
  if (seccomp_policy_dir.empty()) {
    (*dictionary_)[kSeccompPolicyDir] = seccomp_policy_dir;
    return;
  }
  SetPath(kSeccompPolicyDir, seccomp_policy_dir);
}
std::string CuttlefishConfig::seccomp_policy_dir() const {
  return (*dictionary_)[kSeccompPolicyDir].asString();
}

static constexpr char kEnableWebRTC[] = "enable_webrtc";
void CuttlefishConfig::set_enable_webrtc(bool enable_webrtc) {
  (*dictionary_)[kEnableWebRTC] = enable_webrtc;
}
bool CuttlefishConfig::enable_webrtc() const {
  return (*dictionary_)[kEnableWebRTC].asBool();
}

static constexpr char kEnableVehicleHalServer[] = "enable_vehicle_hal_server";
void CuttlefishConfig::set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server) {
  (*dictionary_)[kEnableVehicleHalServer] = enable_vehicle_hal_grpc_server;
}
bool CuttlefishConfig::enable_vehicle_hal_grpc_server() const {
  return (*dictionary_)[kEnableVehicleHalServer].asBool();
}

static constexpr char kVehicleHalServerBinary[] = "vehicle_hal_server_binary";
void CuttlefishConfig::set_vehicle_hal_grpc_server_binary(const std::string& vehicle_hal_server_binary) {
  (*dictionary_)[kVehicleHalServerBinary] = vehicle_hal_server_binary;
}
std::string CuttlefishConfig::vehicle_hal_grpc_server_binary() const {
  return (*dictionary_)[kVehicleHalServerBinary].asString();
}

static constexpr char kCustomActions[] = "custom_actions";
void CuttlefishConfig::set_custom_actions(const std::vector<CustomActionConfig>& actions) {
  Json::Value actions_array(Json::arrayValue);
  for (const auto& action : actions) {
    actions_array.append(action.ToJson());
  }
  (*dictionary_)[kCustomActions] = actions_array;
}
std::vector<CustomActionConfig> CuttlefishConfig::custom_actions() const {
  std::vector<CustomActionConfig> result;
  for (Json::Value custom_action : (*dictionary_)[kCustomActions]) {
    result.push_back(CustomActionConfig(custom_action));
  }
  return result;
}

static constexpr char kWebRTCAssetsDir[] = "webrtc_assets_dir";
void CuttlefishConfig::set_webrtc_assets_dir(const std::string& webrtc_assets_dir) {
  (*dictionary_)[kWebRTCAssetsDir] = webrtc_assets_dir;
}
std::string CuttlefishConfig::webrtc_assets_dir() const {
  return (*dictionary_)[kWebRTCAssetsDir].asString();
}

static constexpr char kWebRTCEnableADBWebSocket[] =
    "webrtc_enable_adb_websocket";
void CuttlefishConfig::set_webrtc_enable_adb_websocket(bool enable) {
    (*dictionary_)[kWebRTCEnableADBWebSocket] = enable;
}
bool CuttlefishConfig::webrtc_enable_adb_websocket() const {
    return (*dictionary_)[kWebRTCEnableADBWebSocket].asBool();
}

static constexpr char kRestartSubprocesses[] = "restart_subprocesses";
bool CuttlefishConfig::restart_subprocesses() const {
  return (*dictionary_)[kRestartSubprocesses].asBool();
}
void CuttlefishConfig::set_restart_subprocesses(bool restart_subprocesses) {
  (*dictionary_)[kRestartSubprocesses] = restart_subprocesses;
}

static constexpr char kRunAdbConnector[] = "run_adb_connector";
bool CuttlefishConfig::run_adb_connector() const {
  return (*dictionary_)[kRunAdbConnector].asBool();
}
void CuttlefishConfig::set_run_adb_connector(bool run_adb_connector) {
  (*dictionary_)[kRunAdbConnector] = run_adb_connector;
}

static constexpr char kRunAsDaemon[] = "run_as_daemon";
bool CuttlefishConfig::run_as_daemon() const {
  return (*dictionary_)[kRunAsDaemon].asBool();
}
void CuttlefishConfig::set_run_as_daemon(bool run_as_daemon) {
  (*dictionary_)[kRunAsDaemon] = run_as_daemon;
}

static constexpr char kDataPolicy[] = "data_policy";
std::string CuttlefishConfig::data_policy() const {
  return (*dictionary_)[kDataPolicy].asString();
}
void CuttlefishConfig::set_data_policy(const std::string& data_policy) {
  (*dictionary_)[kDataPolicy] = data_policy;
}

static constexpr char kBlankDataImageMb[] = "blank_data_image_mb";
int CuttlefishConfig::blank_data_image_mb() const {
  return (*dictionary_)[kBlankDataImageMb].asInt();
}
void CuttlefishConfig::set_blank_data_image_mb(int blank_data_image_mb) {
  (*dictionary_)[kBlankDataImageMb] = blank_data_image_mb;
}

static constexpr char kBlankDataImageFmt[] = "blank_data_image_fmt";
std::string CuttlefishConfig::blank_data_image_fmt() const {
  return (*dictionary_)[kBlankDataImageFmt].asString();
}
void CuttlefishConfig::set_blank_data_image_fmt(const std::string& blank_data_image_fmt) {
  (*dictionary_)[kBlankDataImageFmt] = blank_data_image_fmt;
}

static constexpr char kBootloader[] = "bootloader";
std::string CuttlefishConfig::bootloader() const {
  return (*dictionary_)[kBootloader].asString();
}
void CuttlefishConfig::set_bootloader(const std::string& bootloader) {
  SetPath(kBootloader, bootloader);
}

static constexpr char kBootSlot[] = "boot_slot";
void CuttlefishConfig::set_boot_slot(const std::string& boot_slot) {
  (*dictionary_)[kBootSlot] = boot_slot;
}
std::string CuttlefishConfig::boot_slot() const {
  return (*dictionary_)[kBootSlot].asString();
}

static constexpr char kWebRTCCertsDir[] = "webrtc_certs_dir";
void CuttlefishConfig::set_webrtc_certs_dir(const std::string& certs_dir) {
  (*dictionary_)[kWebRTCCertsDir] = certs_dir;
}
std::string CuttlefishConfig::webrtc_certs_dir() const {
  return (*dictionary_)[kWebRTCCertsDir].asString();
}

static constexpr char kSigServerPort[] = "webrtc_sig_server_port";
void CuttlefishConfig::set_sig_server_port(int port) {
  (*dictionary_)[kSigServerPort] = port;
}
int CuttlefishConfig::sig_server_port() const {
  return (*dictionary_)[kSigServerPort].asInt();
}

static constexpr char kWebrtcUdpPortRange[] = "webrtc_udp_port_range";
void CuttlefishConfig::set_webrtc_udp_port_range(
    std::pair<uint16_t, uint16_t> range) {
  Json::Value arr(Json::ValueType::arrayValue);
  arr[0] = range.first;
  arr[1] = range.second;
  (*dictionary_)[kWebrtcUdpPortRange] = arr;
}
std::pair<uint16_t, uint16_t> CuttlefishConfig::webrtc_udp_port_range() const {
  std::pair<uint16_t, uint16_t> ret;
  ret.first = (*dictionary_)[kWebrtcUdpPortRange][0].asInt();
  ret.second = (*dictionary_)[kWebrtcUdpPortRange][1].asInt();
  return ret;
}

static constexpr char kWebrtcTcpPortRange[] = "webrtc_tcp_port_range";
void CuttlefishConfig::set_webrtc_tcp_port_range(
    std::pair<uint16_t, uint16_t> range) {
  Json::Value arr(Json::ValueType::arrayValue);
  arr[0] = range.first;
  arr[1] = range.second;
  (*dictionary_)[kWebrtcTcpPortRange] = arr;
}
std::pair<uint16_t, uint16_t> CuttlefishConfig::webrtc_tcp_port_range() const {
  std::pair<uint16_t, uint16_t> ret;
  ret.first = (*dictionary_)[kWebrtcTcpPortRange][0].asInt();
  ret.second = (*dictionary_)[kWebrtcTcpPortRange][1].asInt();
  return ret;
}

static constexpr char kSigServerAddress[] = "webrtc_sig_server_addr";
void CuttlefishConfig::set_sig_server_address(const std::string& addr) {
  (*dictionary_)[kSigServerAddress] = addr;
}
std::string CuttlefishConfig::sig_server_address() const {
  return (*dictionary_)[kSigServerAddress].asString();
}

static constexpr char kSigServerPath[] = "webrtc_sig_server_path";
void CuttlefishConfig::set_sig_server_path(const std::string& path) {
  // Don't use SetPath here, it's a URL path not a file system path
  (*dictionary_)[kSigServerPath] = path;
}
std::string CuttlefishConfig::sig_server_path() const {
  return (*dictionary_)[kSigServerPath].asString();
}

static constexpr char kSigServerStrict[] = "webrtc_sig_server_strict";
void CuttlefishConfig::set_sig_server_strict(bool strict) {
  (*dictionary_)[kSigServerStrict] = strict;
}
bool CuttlefishConfig::sig_server_strict() const {
  return (*dictionary_)[kSigServerStrict].asBool();
}

static constexpr char kSigServerHeadersPath[] =
    "webrtc_sig_server_headers_path";
void CuttlefishConfig::set_sig_server_headers_path(const std::string& path) {
  SetPath(kSigServerHeadersPath, path);
}
std::string CuttlefishConfig::sig_server_headers_path() const {
  return (*dictionary_)[kSigServerHeadersPath].asString();
}

static constexpr char kRunModemSimulator[] = "enable_modem_simulator";
bool CuttlefishConfig::enable_modem_simulator() const {
  return (*dictionary_)[kRunModemSimulator].asBool();
}
void CuttlefishConfig::set_enable_modem_simulator(bool enable_modem_simulator) {
  (*dictionary_)[kRunModemSimulator] = enable_modem_simulator;
}

static constexpr char kModemSimulatorInstanceNumber[] =
    "modem_simulator_instance_number";
void CuttlefishConfig::set_modem_simulator_instance_number(
    int instance_number) {
  (*dictionary_)[kModemSimulatorInstanceNumber] = instance_number;
}
int CuttlefishConfig::modem_simulator_instance_number() const {
  return (*dictionary_)[kModemSimulatorInstanceNumber].asInt();
}

static constexpr char kModemSimulatorSimType[] = "modem_simulator_sim_type";
void CuttlefishConfig::set_modem_simulator_sim_type(int sim_type) {
  (*dictionary_)[kModemSimulatorSimType] = sim_type;
}
int CuttlefishConfig::modem_simulator_sim_type() const {
  return (*dictionary_)[kModemSimulatorSimType].asInt();
}

static constexpr char kHostToolsVersion[] = "host_tools_version";
void CuttlefishConfig::set_host_tools_version(
    const std::map<std::string, uint32_t>& versions) {
  Json::Value json(Json::objectValue);
  for (const auto& [key, value] : versions) {
    json[key] = value;
  }
  (*dictionary_)[kHostToolsVersion] = json;
}
std::map<std::string, uint32_t> CuttlefishConfig::host_tools_version() const {
  if (!dictionary_->isMember(kHostToolsVersion)) {
    return {};
  }
  std::map<std::string, uint32_t> versions;
  const auto& elem = (*dictionary_)[kHostToolsVersion];
  for (auto it = elem.begin(); it != elem.end(); it++) {
    versions[it.key().asString()] = it->asUInt();
  }
  return versions;
}

static constexpr char kGuestEnforceSecurity[] = "guest_enforce_security";
void CuttlefishConfig::set_guest_enforce_security(bool guest_enforce_security) {
  (*dictionary_)[kGuestEnforceSecurity] = guest_enforce_security;
}
bool CuttlefishConfig::guest_enforce_security() const {
  return (*dictionary_)[kGuestEnforceSecurity].asBool();
}

const char* kGuestAuditSecurity = "guest_audit_security";
void CuttlefishConfig::set_guest_audit_security(bool guest_audit_security) {
  (*dictionary_)[kGuestAuditSecurity] = guest_audit_security;
}
bool CuttlefishConfig::guest_audit_security() const {
  return (*dictionary_)[kGuestAuditSecurity].asBool();
}

static constexpr char kenableHostBluetooth[] = "enable_host_bluetooth";
void CuttlefishConfig::set_enable_host_bluetooth(bool enable_host_bluetooth) {
  (*dictionary_)[kenableHostBluetooth] = enable_host_bluetooth;
}
bool CuttlefishConfig::enable_host_bluetooth() const {
  return (*dictionary_)[kenableHostBluetooth].asBool();
}

static constexpr char kEnableMetrics[] = "enable_metrics";
void CuttlefishConfig::set_enable_metrics(std::string enable_metrics) {
  (*dictionary_)[kEnableMetrics] = kUnknown;
  if (!enable_metrics.empty()) {
    switch (enable_metrics.at(0)) {
      case 'y':
      case 'Y':
        (*dictionary_)[kEnableMetrics] = kYes;
        break;
      case 'n':
      case 'N':
        (*dictionary_)[kEnableMetrics] = kNo;
        break;
    }
  }
}
CuttlefishConfig::Answer CuttlefishConfig::enable_metrics() const {
  return (CuttlefishConfig::Answer)(*dictionary_)[kEnableMetrics].asInt();
}

static constexpr char kMetricsBinary[] = "metrics_binary";
void CuttlefishConfig::set_metrics_binary(const std::string& metrics_binary) {
  (*dictionary_)[kMetricsBinary] = metrics_binary;
}
std::string CuttlefishConfig::metrics_binary() const {
  return (*dictionary_)[kMetricsBinary].asString();
}

static constexpr char kExtraKernelCmdline[] = "extra_kernel_cmdline";
void CuttlefishConfig::set_extra_kernel_cmdline(std::string extra_cmdline) {
  Json::Value args_json_obj(Json::arrayValue);
  for (const auto& arg : android::base::Split(extra_cmdline, " ")) {
    args_json_obj.append(arg);
  }
  (*dictionary_)[kExtraKernelCmdline] = args_json_obj;
}
std::vector<std::string> CuttlefishConfig::extra_kernel_cmdline() const {
  std::vector<std::string> cmdline;
  for (const Json::Value& arg : (*dictionary_)[kExtraKernelCmdline]) {
    cmdline.push_back(arg.asString());
  }
  return cmdline;
}

static constexpr char kRilDns[] = "ril_dns";
void CuttlefishConfig::set_ril_dns(const std::string& ril_dns) {
  (*dictionary_)[kRilDns] = ril_dns;
}
std::string CuttlefishConfig::ril_dns() const {
  return (*dictionary_)[kRilDns].asString();
}

static constexpr char kKgdb[] = "kgdb";
void CuttlefishConfig::set_kgdb(bool kgdb) {
  (*dictionary_)[kKgdb] = kgdb;
}
bool CuttlefishConfig::kgdb() const {
  return (*dictionary_)[kKgdb].asBool();
}

static constexpr char kEnableMinimalMode[] = "enable_minimal_mode";
bool CuttlefishConfig::enable_minimal_mode() const {
  return (*dictionary_)[kEnableMinimalMode].asBool();
}
void CuttlefishConfig::set_enable_minimal_mode(bool enable_minimal_mode) {
  (*dictionary_)[kEnableMinimalMode] = enable_minimal_mode;
}

static constexpr char kConsole[] = "console";
void CuttlefishConfig::set_console(bool console) {
  (*dictionary_)[kConsole] = console;
}
bool CuttlefishConfig::console() const {
  return (*dictionary_)[kConsole].asBool();
}
std::string CuttlefishConfig::console_dev() const {
  auto can_use_virtio_console = !kgdb() && !use_bootloader();
  std::string console_dev;
  if (can_use_virtio_console) {
    // If kgdb and the bootloader are disabled, the Android serial console
    // spawns on a virtio-console port. If the bootloader is enabled, virtio
    // console can't be used since uboot doesn't support it.
    console_dev = "hvc1";
  } else {
    // crosvm ARM does not support ttyAMA. ttyAMA is a part of ARM arch.
    Arch target = target_arch();
    if ((target == Arch::Arm64 || target == Arch::Arm) &&
        vm_manager() != vm_manager::CrosvmManager::name()) {
      console_dev = "ttyAMA0";
    } else {
      console_dev = "ttyS0";
    }
  }
  return console_dev;
}

static constexpr char kVhostNet[] = "vhost_net";
void CuttlefishConfig::set_vhost_net(bool vhost_net) {
  (*dictionary_)[kVhostNet] = vhost_net;
}
bool CuttlefishConfig::vhost_net() const {
  return (*dictionary_)[kVhostNet].asBool();
}

static constexpr char kRecordScreen[] = "record_screen";
void CuttlefishConfig::set_record_screen(bool record_screen) {
  (*dictionary_)[kRecordScreen] = record_screen;
}
bool CuttlefishConfig::record_screen() const {
  return (*dictionary_)[kRecordScreen].asBool();
}

static constexpr char kSmt[] = "smt";
void CuttlefishConfig::set_smt(bool smt) {
  (*dictionary_)[kSmt] = smt;
}
bool CuttlefishConfig::smt() const {
  return (*dictionary_)[kSmt].asBool();
}

static constexpr char kEnableAudio[] = "enable_audio";
void CuttlefishConfig::set_enable_audio(bool enable) {
  (*dictionary_)[kEnableAudio] = enable;
}
bool CuttlefishConfig::enable_audio() const {
  return (*dictionary_)[kEnableAudio].asBool();
}

static constexpr char kProtectedVm[] = "protected_vm";
void CuttlefishConfig::set_protected_vm(bool protected_vm) {
  (*dictionary_)[kProtectedVm] = protected_vm;
}
bool CuttlefishConfig::protected_vm() const {
  return (*dictionary_)[kProtectedVm].asBool();
}

static constexpr char kTargetArch[] = "target_arch";
void CuttlefishConfig::set_target_arch(Arch target_arch) {
  (*dictionary_)[kTargetArch] = static_cast<int>(target_arch);
}
Arch CuttlefishConfig::target_arch() const {
  return static_cast<Arch>((*dictionary_)[kTargetArch].asInt());
}

static constexpr char kBootconfigSupported[] = "bootconfig_supported";
bool CuttlefishConfig::bootconfig_supported() const {
  return (*dictionary_)[kBootconfigSupported].asBool();
}
void CuttlefishConfig::set_bootconfig_supported(bool bootconfig_supported) {
  (*dictionary_)[kBootconfigSupported] = bootconfig_supported;
}

// Creates the (initially empty) config object and populates it with values from
// the config file if the CUTTLEFISH_CONFIG_FILE env variable is present.
// Returns nullptr if there was an error loading from file
/*static*/ CuttlefishConfig* CuttlefishConfig::BuildConfigImpl() {
  auto config_file_path = StringFromEnv(kCuttlefishConfigEnvVarName,
                                        GetGlobalConfigFileLink());
  auto ret = new CuttlefishConfig();
  if (ret) {
    auto loaded = ret->LoadFromFile(config_file_path.c_str());
    if (!loaded) {
      delete ret;
      return nullptr;
    }
  }
  return ret;
}

/*static*/ const CuttlefishConfig* CuttlefishConfig::Get() {
  static std::shared_ptr<CuttlefishConfig> config(BuildConfigImpl());
  return config.get();
}

/*static*/ bool CuttlefishConfig::ConfigExists() {
  auto config_file_path = StringFromEnv(kCuttlefishConfigEnvVarName,
                                        GetGlobalConfigFileLink());
  auto real_file_path = AbsolutePath(config_file_path.c_str());
  return FileExists(real_file_path);
}

CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {}
// Can't use '= default' on the header because the compiler complains of
// Json::Value being an incomplete type
CuttlefishConfig::~CuttlefishConfig() = default;

CuttlefishConfig::CuttlefishConfig(CuttlefishConfig&&) = default;
CuttlefishConfig& CuttlefishConfig::operator=(CuttlefishConfig&&) = default;

bool CuttlefishConfig::LoadFromFile(const char* file) {
  auto real_file_path = AbsolutePath(file);
  if (real_file_path.empty()) {
    LOG(ERROR) << "Could not get real path for file " << file;
    return false;
  }
  Json::CharReaderBuilder builder;
  std::ifstream ifs(real_file_path);
  std::string errorMessage;
  if (!Json::parseFromStream(builder, ifs, dictionary_.get(), &errorMessage)) {
    LOG(ERROR) << "Could not read config file " << file << ": " << errorMessage;
    return false;
  }
  return true;
}
bool CuttlefishConfig::SaveToFile(const std::string& file) const {
  std::ofstream ofs(file);
  if (!ofs.is_open()) {
    LOG(ERROR) << "Unable to write to file " << file;
    return false;
  }
  ofs << *dictionary_;
  return !ofs.fail();
}

std::string CuttlefishConfig::AssemblyPath(
    const std::string& file_name) const {
  return AbsolutePath(assembly_dir() + "/" + file_name);
}

CuttlefishConfig::MutableInstanceSpecific CuttlefishConfig::ForInstance(int num) {
  return MutableInstanceSpecific(this, std::to_string(num));
}

CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForInstance(int num) const {
  return InstanceSpecific(this, std::to_string(num));
}

CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForDefaultInstance() const {
  return InstanceSpecific(this, std::to_string(GetInstance()));
}

std::vector<CuttlefishConfig::InstanceSpecific> CuttlefishConfig::Instances() const {
  const auto& json = (*dictionary_)[kInstances];
  std::vector<CuttlefishConfig::InstanceSpecific> instances;
  for (const auto& name : json.getMemberNames()) {
    instances.push_back(CuttlefishConfig::InstanceSpecific(this, name));
  }
  return instances;
}

int GetInstance() {
  static int instance_id = InstanceFromEnvironment();
  return instance_id;
}

int GetDefaultVsockCid() {
  // we assume that this function is used to configure CuttlefishConfig once
  static const int default_vsock_cid = 3 + GetInstance() - 1;
  return default_vsock_cid;
}

int GetVsockServerPort(const int base,
                       const int vsock_guest_cid /**< per instance guest cid */) {
    return base + (vsock_guest_cid - 3);
}

std::string GetGlobalConfigFileLink() {
  return StringFromEnv("HOME", ".") + "/.cuttlefish_config.json";
}

std::string ForCurrentInstance(const char* prefix) {
  std::ostringstream stream;
  stream << prefix << std::setfill('0') << std::setw(2) << GetInstance();
  return stream.str();
}
int ForCurrentInstance(int base) { return base + GetInstance() - 1; }

std::string RandomSerialNumber(const std::string& prefix) {
  const char hex_characters[] = "0123456789ABCDEF";
  std::srand(time(0));
  char str[10];
  for(int i=0; i<10; i++){
    str[i] = hex_characters[rand() % strlen(hex_characters)];
  }
  return prefix + str;
}

std::string DefaultHostArtifactsPath(const std::string& file_name) {
  return (StringFromEnv("ANDROID_SOONG_HOST_OUT", StringFromEnv("HOME", ".")) + "/") +
         file_name;
}

std::string HostBinaryPath(const std::string& binary_name) {
#ifdef __ANDROID__
  return binary_name;
#else
  return DefaultHostArtifactsPath("bin/" + binary_name);
#endif
}

std::string DefaultGuestImagePath(const std::string& file_name) {
  return (StringFromEnv("ANDROID_PRODUCT_OUT", StringFromEnv("HOME", "."))) +
         file_name;
}

bool HostSupportsQemuCli() {
  static bool supported =
      std::system(
          "/usr/lib/cuttlefish-common/bin/capability_query.py qemu_cli") == 0;
  return supported;
}

}  // namespace cuttlefish
