/*
 * 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 <climits>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>

#include <gflags/gflags.h>
#include <glog/logging.h>
#include <json/json.h>

#include "common/libs/utils/environment.h"
#include "common/libs/utils/files.h"

DEFINE_string(config_file,
              vsoc::GetDefaultPerInstanceDir() + "/cuttlefish_config.json",
              "A file from where to load the config values. This flag is "
              "ignored by the launcher");

namespace {

constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";

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

  // CUTTLEFISH_INSTANCE environment variable
  const char* instance_str = std::getenv(kInstanceEnvironmentVariable);
  if (!instance_str) {
    // Try to get it from the user instead
    instance_str = std::getenv("USER");
    if (!instance_str || std::strncmp(instance_str, kVsocUserPrefix,
                                      sizeof(kVsocUserPrefix) - 1)) {
      // No user or we don't recognize this user
      return kDefaultInstance;
    }
    instance_str += sizeof(kVsocUserPrefix) - 1;
    // Set the environment variable so that child processes see it
    setenv(kInstanceEnvironmentVariable, instance_str, 0);
  }

  int instance = std::atoi(instance_str);
  if (instance <= 0) {
    instance = kDefaultInstance;
  }

  return instance;
}

const char* kSerialNumber = "serial_number";
const char* kInstanceDir = "instance_dir";

const char* kCpus = "cpus";
const char* kMemoryMb = "memory_mb";
const char* kDpi = "dpi";
const char* kXRes = "x_res";
const char* kYRes = "y_res";
const char* kRefreshRateHz = "refresh_rate_hz";

const char* kKernelImagePath = "kernel_image_path";
const char* kGdbFlag = "gdb_flag";
const char* kKernelArgs = "kernel_args";
const char* kRamdiskImagePath = "ramdisk_image_path";

const char* kSystemImagePath = "system_image_path";
const char* kCacheImagePath = "cache_image_path";
const char* kDataImagePath = "data_image_path";
const char* kVendorImagePath = "vendor_image_path";
const char* kUsbV1SocketName = "usb_v1_socket_name";
const char* kVhciPort = "vhci_port";
const char* kUsbIpSocketName = "usb_ip_socket_name";
const char* kKernelLogSocketName = "kernel_log_socket_name";
const char* kConsolePath = "console_path";
const char* kLogcatPath = "logcat_path";
const char* kDtbPath = "dtb_path";

const char* kMempath = "mempath";
const char* kIvshmemQemuSocketPath = "ivshmem_qemu_socket_path";
const char* kIvshmemClientSocketPath = "ivshmem_client_socket_path";
const char* kIvshmemVectorCount = "ivshmem_vector_count";

const char* kMobileBridgeName = "mobile_bridge_name";
const char* kMobileTapName = "mobile_tap_name";
const char* kWifiBridgeName = "wifi_bridge_name";
const char* kWifiTapName = "wifi_tap_name";
const char* kWifiGuestMacAddr = "wifi_guest_mac_addr";
const char* kWifiHostMacAddr = "wifi_host_mac_addr";
const char* kEntropySource = "entropy_source";

const char* kUuid = "uuid";
const char* kDisableDacSecurity = "disable_dac_security";
const char* kDisableAppArmorSecurity = "disable_app_armor_security";
const char* kCuttlefishEnvPath = "cuttlefish_env_path";

const char* kAdbMode = "adb_mode";
}  // namespace

namespace vsoc {

std::string CuttlefishConfig::instance_dir() const {
  return (*dictionary_)[kInstanceDir].asString();
}
void CuttlefishConfig::set_instance_dir(const std::string& instance_dir) {
  (*dictionary_)[kInstanceDir] = instance_dir;
}

std::string CuttlefishConfig::serial_number() const {
  return (*dictionary_)[kSerialNumber].asString();
}
void CuttlefishConfig::set_serial_number(const std::string& serial_number) {
  (*dictionary_)[kSerialNumber] = serial_number;
}

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

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

int CuttlefishConfig::dpi() const { return (*dictionary_)[kDpi].asInt(); }
void CuttlefishConfig::set_dpi(int dpi) { (*dictionary_)[kDpi] = dpi; }

int CuttlefishConfig::x_res() const { return (*dictionary_)[kXRes].asInt(); }
void CuttlefishConfig::set_x_res(int x_res) { (*dictionary_)[kXRes] = x_res; }

int CuttlefishConfig::y_res() const { return (*dictionary_)[kYRes].asInt(); }
void CuttlefishConfig::set_y_res(int y_res) { (*dictionary_)[kYRes] = y_res; }

int CuttlefishConfig::refresh_rate_hz() const {
  return (*dictionary_)[kRefreshRateHz].asInt();
}
void CuttlefishConfig::set_refresh_rate_hz(int refresh_rate_hz) {
  (*dictionary_)[kRefreshRateHz] = refresh_rate_hz;
}

std::string CuttlefishConfig::kernel_image_path() const {
  return (*dictionary_)[kKernelImagePath].asString();
}

void CuttlefishConfig::set_kernel_image_path(
    const std::string& kernel_image_path) {
  (*dictionary_)[kKernelImagePath] = kernel_image_path;
}

std::string CuttlefishConfig::gdb_flag() const {
  return (*dictionary_)[kGdbFlag].asString();
}

void CuttlefishConfig::set_gdb_flag(
    const std::string& device) {
  (*dictionary_)[kGdbFlag] = device;
}

std::string CuttlefishConfig::kernel_args() const {
  return (*dictionary_)[kKernelArgs].asString();
}
void CuttlefishConfig::set_kernel_args(const std::string& kernel_args) {
  (*dictionary_)[kKernelArgs] = kernel_args;
}

std::string CuttlefishConfig::ramdisk_image_path() const {
  return (*dictionary_)[kRamdiskImagePath].asString();
}
void CuttlefishConfig::set_ramdisk_image_path(
    const std::string& ramdisk_image_path) {
  (*dictionary_)[kRamdiskImagePath] = ramdisk_image_path;
}

std::string CuttlefishConfig::system_image_path() const {
  return (*dictionary_)[kSystemImagePath].asString();
}
void CuttlefishConfig::set_system_image_path(
    const std::string& system_image_path) {
  (*dictionary_)[kSystemImagePath] = system_image_path;
}

std::string CuttlefishConfig::cache_image_path() const {
  return (*dictionary_)[kCacheImagePath].asString();
}
void CuttlefishConfig::set_cache_image_path(
    const std::string& cache_image_path) {
  (*dictionary_)[kCacheImagePath] = cache_image_path;
}

std::string CuttlefishConfig::data_image_path() const {
  return (*dictionary_)[kDataImagePath].asString();
}
void CuttlefishConfig::set_data_image_path(const std::string& data_image_path) {
  (*dictionary_)[kDataImagePath] = data_image_path;
}

std::string CuttlefishConfig::vendor_image_path() const {
  return (*dictionary_)[kVendorImagePath].asString();
}
void CuttlefishConfig::set_vendor_image_path(
    const std::string& vendor_image_path) {
  (*dictionary_)[kVendorImagePath] = vendor_image_path;
}

std::string CuttlefishConfig::dtb_path() const {
  return (*dictionary_)[kDtbPath].asString();
}
void CuttlefishConfig::set_dtb_path(const std::string& dtb_path) {
  (*dictionary_)[kDtbPath] = dtb_path;
}

std::string CuttlefishConfig::mempath() const {
  return (*dictionary_)[kMempath].asString();
}
void CuttlefishConfig::set_mempath(const std::string& mempath) {
  (*dictionary_)[kMempath] = mempath;
}

std::string CuttlefishConfig::ivshmem_qemu_socket_path() const {
  return (*dictionary_)[kIvshmemQemuSocketPath].asString();
}
void CuttlefishConfig::set_ivshmem_qemu_socket_path(
    const std::string& ivshmem_qemu_socket_path) {
  (*dictionary_)[kIvshmemQemuSocketPath] = ivshmem_qemu_socket_path;
}

std::string CuttlefishConfig::ivshmem_client_socket_path() const {
  return (*dictionary_)[kIvshmemClientSocketPath].asString();
}
void CuttlefishConfig::set_ivshmem_client_socket_path(
    const std::string& ivshmem_client_socket_path) {
  (*dictionary_)[kIvshmemClientSocketPath] = ivshmem_client_socket_path;
}

int CuttlefishConfig::ivshmem_vector_count() const {
  return (*dictionary_)[kIvshmemVectorCount].asInt();
}
void CuttlefishConfig::set_ivshmem_vector_count(int ivshmem_vector_count) {
  (*dictionary_)[kIvshmemVectorCount] = ivshmem_vector_count;
}

std::string CuttlefishConfig::usb_v1_socket_name() const {
  return (*dictionary_)[kUsbV1SocketName].asString();
}
void CuttlefishConfig::set_usb_v1_socket_name(
    const std::string& usb_v1_socket_name) {
  (*dictionary_)[kUsbV1SocketName] = usb_v1_socket_name;
}

int CuttlefishConfig::vhci_port() const {
  return (*dictionary_)[kVhciPort].asInt();
}
void CuttlefishConfig::set_vhci_port(int vhci_port) {
  (*dictionary_)[kVhciPort] = vhci_port;
}

std::string CuttlefishConfig::usb_ip_socket_name() const {
  return (*dictionary_)[kUsbIpSocketName].asString();
}
void CuttlefishConfig::set_usb_ip_socket_name(
    const std::string& usb_ip_socket_name) {
  (*dictionary_)[kUsbIpSocketName] = usb_ip_socket_name;
}

std::string CuttlefishConfig::kernel_log_socket_name() const {
  return (*dictionary_)[kKernelLogSocketName].asString();
}
void CuttlefishConfig::set_kernel_log_socket_name(
    const std::string& kernel_log_socket_name) {
  (*dictionary_)[kKernelLogSocketName] = kernel_log_socket_name;
}

std::string CuttlefishConfig::console_path() const {
  return (*dictionary_)[kConsolePath].asString();
}
void CuttlefishConfig::set_console_path(const std::string& console_path) {
  (*dictionary_)[kConsolePath] = console_path;
}

std::string CuttlefishConfig::logcat_path() const {
  return (*dictionary_)[kLogcatPath].asString();
}
void CuttlefishConfig::set_logcat_path(const std::string& logcat_path) {
  (*dictionary_)[kLogcatPath] = logcat_path;
}

std::string CuttlefishConfig::mobile_bridge_name() const {
  return (*dictionary_)[kMobileBridgeName].asString();
}
void CuttlefishConfig::set_mobile_bridge_name(
    const std::string& mobile_bridge_name) {
  (*dictionary_)[kMobileBridgeName] = mobile_bridge_name;
}

std::string CuttlefishConfig::wifi_bridge_name() const {
  return (*dictionary_)[kWifiBridgeName].asString();
}
void CuttlefishConfig::set_wifi_bridge_name(
    const std::string& wifi_bridge_name) {
  (*dictionary_)[kWifiBridgeName] = wifi_bridge_name;
}

std::string CuttlefishConfig::wifi_guest_mac_addr() const {
  return (*dictionary_)[kWifiGuestMacAddr].asString();
}
void CuttlefishConfig::set_wifi_guest_mac_addr(
    const std::string& wifi_guest_mac_addr) {
  (*dictionary_)[kWifiGuestMacAddr] = wifi_guest_mac_addr;
}

std::string CuttlefishConfig::wifi_host_mac_addr() const {
  return (*dictionary_)[kWifiHostMacAddr].asString();
}
void CuttlefishConfig::set_wifi_host_mac_addr(
    const std::string& wifi_host_mac_addr) {
  (*dictionary_)[kWifiHostMacAddr] = wifi_host_mac_addr;
}

std::string CuttlefishConfig::mobile_tap_name() const {
  return (*dictionary_)[kMobileTapName].asString();
}
void CuttlefishConfig::set_mobile_tap_name(const std::string& mobile_tap_name) {
  (*dictionary_)[kMobileTapName] = mobile_tap_name;
}

std::string CuttlefishConfig::wifi_tap_name() const {
  return (*dictionary_)[kWifiTapName].asString();
}
void CuttlefishConfig::set_wifi_tap_name(const std::string& wifi_tap_name) {
  (*dictionary_)[kWifiTapName] = wifi_tap_name;
}

std::string CuttlefishConfig::entropy_source() const {
  return (*dictionary_)[kEntropySource].asString();
}
void CuttlefishConfig::set_entropy_source(const std::string& entropy_source) {
  (*dictionary_)[kEntropySource] = entropy_source;
}

std::string CuttlefishConfig::uuid() const {
  return (*dictionary_)[kUuid].asString();
}
void CuttlefishConfig::set_uuid(const std::string& uuid) {
  (*dictionary_)[kUuid] = uuid;
}

bool CuttlefishConfig::disable_dac_security() const {
  return (*dictionary_)[kDisableDacSecurity].asBool();
}
void CuttlefishConfig::set_disable_dac_security(bool disable_dac_security) {
  (*dictionary_)[kDisableDacSecurity] = disable_dac_security;
}

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

bool CuttlefishConfig::disable_app_armor_security() const {
  return (*dictionary_)[kDisableAppArmorSecurity].asBool();
}
void CuttlefishConfig::set_disable_app_armor_security(
    bool disable_app_armor_security) {
  (*dictionary_)[kDisableAppArmorSecurity] = disable_app_armor_security;
}

std::string CuttlefishConfig::adb_mode() const {
  return (*dictionary_)[kAdbMode].asString();
}

void CuttlefishConfig::set_adb_mode(const std::string& mode) {
  (*dictionary_)[kAdbMode] = mode;
}

/*static*/ CuttlefishConfig* CuttlefishConfig::Get() {
  static CuttlefishConfig config;
  return &config;
}

CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {
  if (!FLAGS_config_file.empty()) {
    LoadFromFile(FLAGS_config_file.c_str());
  }
}

void CuttlefishConfig::LoadFromFile(const char* file) {
  auto real_file_path = cvd::RealPath(file);
  if (real_file_path.empty()) {
    LOG(FATAL) << "Could not get real path for file " << file;
  }
  Json::Reader reader;
  std::ifstream ifs(real_file_path);
  if (!reader.parse(ifs, *dictionary_)) {
    LOG(FATAL) << "Could not read config file " << file << ": "
               << reader.getFormattedErrorMessages();
  }
}
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::PerInstancePath(const char* file_name) const {
  return (instance_dir() + "/") + file_name;
}

std::string CuttlefishConfig::instance_name() const {
  return GetPerInstanceDefault("cvd-");
}

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

std::string GetDomain() {
  return CuttlefishConfig::Get()->ivshmem_client_socket_path();
}

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

std::string GetDefaultPerInstanceDir() {
  std::ostringstream stream;
  if (HostSupportsQemuCli()) {
    stream << std::getenv("HOME") << "/cuttlefish_runtime";
  } else {
    stream << "/var/run/libvirt-" << kDefaultUuidPrefix << std::setfill('0')
           << std::setw(2) << GetInstance();
  }
  return stream.str();
}

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

std::string DefaultGuestImagePath(const std::string& file_name) {
  return (cvd::StringFromEnv("ANDROID_PRODUCT_OUT",
                        cvd::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 vsoc
