// Copyright 2018 The Fuchsia 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 "src/virtualization/lib/guest_config/guest_config.h"

#include <lib/syslog/cpp/macros.h>
#include <libgen.h>
#include <unistd.h>
#include <zircon/device/block.h>

#include <functional>
#include <iostream>
#include <unordered_map>
#include <utility>

#include <rapidjson/document.h>

#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/strings/string_number_conversions.h"

namespace guest_config {

namespace {

using fuchsia::virtualization::GuestConfig;

constexpr uint64_t kDefaultMemory = 1ul << 30;

// This is a locally administered MAC address (first byte 0x02) mixed with the
// Google Organizationally Unique Identifier (00:1a:11). The host gets ff:ff:ff
// and the guest gets 00:00:00 for the last three octets.
constexpr fuchsia::hardware::ethernet::MacAddress kGuestMacAddress = {
    .octets = {0x02, 0x1a, 0x11, 0x00, 0x01, 0x00},
};

zx_status_t parse(const std::string& name, const std::string& value, bool* result) {
  if (value.empty() || value == "true") {
    *result = true;
  } else if (value == "false") {
    *result = false;
  } else {
    FX_LOGS(ERROR) << "Option '" << name << "' expects either 'true' or 'false'; received '"
                   << value << "'";
    return ZX_ERR_INVALID_ARGS;
  }
  return ZX_OK;
}

zx_status_t parse(const std::string& name, const std::string& value, std::string* result) {
  *result = value;
  return ZX_OK;
}

template <typename NumberType, fxl::Base base = fxl::Base::k10,
          typename = std::enable_if<std::is_integral<NumberType>::value>>
zx_status_t parse(const std::string& name, const std::string& value, NumberType* out) {
  if (!fxl::StringToNumberWithError(value, out, base)) {
    FX_LOGS(ERROR) << "Option '" << name << "': Unable to convert '" << value << "' into a number";
    return ZX_ERR_INVALID_ARGS;
  }
  return ZX_OK;
}

zx_status_t parse(const OpenAt& open_at, const std::string& name, const std::string& value,
                  fuchsia::virtualization::BlockSpec* out) {
  std::string path;
  std::istringstream token_stream(value);
  std::string token;
  while (std::getline(token_stream, token, ',')) {
    if (token == "rw") {
      out->mode = fuchsia::virtualization::BlockMode::READ_WRITE;
    } else if (token == "ro") {
      out->mode = fuchsia::virtualization::BlockMode::READ_ONLY;
    } else if (token == "volatile") {
      out->mode = fuchsia::virtualization::BlockMode::VOLATILE_WRITE;
    } else if (token == "fdio") {
      out->format = fuchsia::virtualization::BlockFormat::RAW;
    } else if (token == "qcow") {
      out->format = fuchsia::virtualization::BlockFormat::QCOW;
    } else {
      // Set the last MAX_BLOCK_DEVICE_ID characters of token as the ID.
      size_t pos = token.size() > fuchsia::virtualization::MAX_BLOCK_DEVICE_ID
                       ? token.size() - fuchsia::virtualization::MAX_BLOCK_DEVICE_ID
                       : 0;
      out->id = token.substr(pos, fuchsia::virtualization::MAX_BLOCK_DEVICE_ID);
      path = std::move(token);
    }
  }
  if (path.empty()) {
    return ZX_ERR_INVALID_ARGS;
  }
  return open_at(path, out->file.NewRequest());
}

std::vector<std::string> split(const std::string& spec, char delim) {
  std::istringstream token_stream(spec);
  std::string token;
  std::vector<std::string> tokens;
  while (std::getline(token_stream, token, delim)) {
    tokens.push_back(token);
  }
  return tokens;
}

zx_status_t parse_memory(const std::string& value, size_t* out) {
  char modifier = 'b';
  size_t size;
  int ret = sscanf(value.c_str(), "%zd%c", &size, &modifier);
  if (ret < 1) {
    FX_LOGS(ERROR) << "Value is not a size string: " << value;
    return ZX_ERR_INVALID_ARGS;
  }

  switch (modifier) {
    case 'b':
      break;
    case 'k':
      size *= (1 << 10);
      break;
    case 'M':
      size *= (1 << 20);
      break;
    case 'G':
      size *= (1 << 30);
      break;
    default:
      FX_LOGS(ERROR) << "Invalid size modifier " << modifier;
      return ZX_ERR_INVALID_ARGS;
  }

  *out = size;
  return ZX_OK;
}

zx_status_t parse(const std::string& name, const std::string& value,
                  fuchsia::virtualization::MemorySpec* out) {
  out->base = 0;
  out->policy = fuchsia::virtualization::MemoryPolicy::GUEST_CACHED;
  std::vector<std::string> tokens = split(value, ',');
  if (tokens.size() == 1) {
    return parse_memory(tokens[0], &out->size);
  }
  if (tokens.size() > 3) {
    return ZX_ERR_INVALID_ARGS;
  }
  zx_status_t status = parse<uint64_t, fxl::Base::k16>(name, tokens[0], &out->base);
  if (status != ZX_OK) {
    return status;
  }
  status = parse_memory(tokens[1], &out->size);
  if (status != ZX_OK) {
    return status;
  }
  if (tokens.size() != 3) {
    return ZX_OK;
  } else if (tokens[2] == "cached") {
    out->policy = fuchsia::virtualization::MemoryPolicy::HOST_CACHED;
  } else if (tokens[2] == "device") {
    out->policy = fuchsia::virtualization::MemoryPolicy::HOST_DEVICE;
  } else {
    return ZX_ERR_INVALID_ARGS;
  }
  return ZX_OK;
}

class OptionHandler {
 public:
  OptionHandler() : has_field_{[](const GuestConfig&) { return false; }} {}
  OptionHandler(std::function<bool(const GuestConfig&)> has_field) : has_field_{has_field} {}

  zx_status_t Set(GuestConfig* cfg, const std::string& name, const std::string& value,
                  bool override) {
    if (override || !has_field_(*cfg)) {
      return SetInternal(cfg, name, value);
    }
    return ZX_OK;
  }

  void MaybeSetDefault(GuestConfig* cfg) {
    if (!has_field_(*cfg)) {
      SetDefault(cfg);
    }
  }

  virtual ~OptionHandler() = default;

 protected:
  virtual zx_status_t SetInternal(GuestConfig* cfg, const std::string& name,
                                  const std::string& value) = 0;
  virtual void SetDefault(GuestConfig* cfg) {}

  std::function<bool(const GuestConfig&)> has_field_;
};

template <typename T, bool require_value = true>
class OptionHandlerWithoutDefaultValue : public OptionHandler {
 public:
  OptionHandlerWithoutDefaultValue(std::function<bool(const GuestConfig&)> has_field,
                                   std::function<T*(GuestConfig*)> mutable_field)
      : OptionHandler{has_field}, mutable_field_{std::move(mutable_field)} {}

 protected:
  void FillMutableField(const T& value, GuestConfig* cfg) { *(mutable_field_(cfg)) = value; }

  zx_status_t SetInternal(GuestConfig* cfg, const std::string& name,
                          const std::string& value) override {
    if (require_value && value.empty()) {
      FX_LOGS(ERROR) << "Option: '" << name << "' expects a value (--" << name << "=<value>)";
      return ZX_ERR_INVALID_ARGS;
    }
    T result;
    auto status = parse(name, value, &result);
    if (status == ZX_OK) {
      FillMutableField(result, cfg);
    }
    return status;
  }

 private:
  std::function<T*(GuestConfig*)> mutable_field_;
};

template <typename T, bool require_value = true>
class OptionHandlerWithDefaultValue : public OptionHandlerWithoutDefaultValue<T, require_value> {
 public:
  OptionHandlerWithDefaultValue(std::function<bool(const GuestConfig&)> has_field,
                                std::function<T*(GuestConfig*)> mutable_field,
                                const T& default_value)
      : OptionHandlerWithoutDefaultValue<T, require_value>{std::move(has_field),
                                                           std::move(mutable_field)},
        default_value_{default_value} {}

 protected:
  void SetDefault(GuestConfig* cfg) override {
    OptionHandlerWithoutDefaultValue<T, require_value>::FillMutableField(default_value_, cfg);
  }

  const T default_value_;
};

using NumCpusOptionHandler = OptionHandlerWithDefaultValue<uint8_t>;
using BoolOptionHandler = OptionHandlerWithDefaultValue<bool, /* require_value */ false>;
using StringOptionHandler = OptionHandlerWithoutDefaultValue<std::string>;

class FileOptionHandler : public OptionHandler {
 public:
  FileOptionHandler(OpenAt open_at, std::function<bool(const GuestConfig&)> has_field,
                    std::function<fuchsia::io::FileHandle*(GuestConfig*)> mutable_field)
      : OptionHandler{has_field},
        open_at_{std::move(open_at)},
        mutable_field_{std::move(mutable_field)} {}

 protected:
  zx_status_t SetInternal(GuestConfig* cfg, const std::string& name,
                          const std::string& value) override {
    if (value.empty()) {
      FX_LOGS(ERROR) << "Option: '" << name << "' expects a value (--" << name << "=<value>)";
      return ZX_ERR_INVALID_ARGS;
    }
    fuchsia::io::FileHandle result;
    zx_status_t status = open_at_(value, result.NewRequest());
    if (status == ZX_OK) {
      *(mutable_field_(cfg)) = std::move(result);
    }
    return status;
  }

 private:
  OpenAt open_at_;
  std::function<fuchsia::io::FileHandle*(GuestConfig*)> mutable_field_;
};

class KernelOptionHandler : public FileOptionHandler {
 public:
  KernelOptionHandler(
      OpenAt open_at, std::function<bool(const GuestConfig&)> has_field,
      std::function<fuchsia::io::FileHandle*(GuestConfig*)> mutable_field,
      std::function<fuchsia::virtualization::KernelType*(GuestConfig*)> mutable_type_fn,
      fuchsia::virtualization::KernelType type)
      : FileOptionHandler{std::move(open_at), std::move(has_field), std::move(mutable_field)},
        mutable_type_fn_{std::move(mutable_type_fn)},
        type_{type} {}

 private:
  zx_status_t SetInternal(GuestConfig* cfg, const std::string& name,
                          const std::string& value) override {
    auto status = FileOptionHandler::SetInternal(cfg, name, value);
    if (status == ZX_OK) {
      *(mutable_type_fn_(cfg)) = type_;
    }
    return status;
  }

  std::function<fuchsia::virtualization::KernelType*(GuestConfig*)> mutable_type_fn_;
  fuchsia::virtualization::KernelType type_;
};

template <typename T>
class RepeatedOptionHandler : public OptionHandler {
 public:
  RepeatedOptionHandler(std::function<std::vector<T>*(GuestConfig*)> mutable_field)
      : mutable_field_{std::move(mutable_field)} {}

 protected:
  zx_status_t SetInternal(GuestConfig* cfg, const std::string& name,
                          const std::string& value) override {
    if (value.empty()) {
      FX_LOGS(ERROR) << "Option: '" << name << "' expects a value (--" << name << "=<value>)";
      return ZX_ERR_INVALID_ARGS;
    }
    T result{};
    auto status = parse(name, value, &result);
    if (status == ZX_OK) {
      mutable_field_(cfg)->emplace_back(result);
    }
    return status;
  }

  void SetDefault(GuestConfig* cfg) override {
    mutable_field_(cfg);  // Fills it with an empty vector.
  }

 private:
  std::function<std::vector<T>*(GuestConfig*)> mutable_field_;
};

template <>
class RepeatedOptionHandler<fuchsia::virtualization::BlockSpec> : public OptionHandler {
 public:
  RepeatedOptionHandler(
      OpenAt open_at,
      std::function<std::vector<fuchsia::virtualization::BlockSpec>*(GuestConfig*)> mutable_field)
      : open_at_(std::move(open_at)), mutable_field_{std::move(mutable_field)} {}

 protected:
  zx_status_t SetInternal(GuestConfig* cfg, const std::string& name,
                          const std::string& value) override {
    if (value.empty()) {
      FX_LOGS(ERROR) << "Option: '" << name << "' expects a value (--" << name << "=<value>)";
      return ZX_ERR_INVALID_ARGS;
    }
    fuchsia::virtualization::BlockSpec result;
    auto status = parse(open_at_, name, value, &result);
    if (status == ZX_OK) {
      mutable_field_(cfg)->emplace_back(std::move(result));
    }
    return status;
  }

 private:
  OpenAt open_at_;
  std::function<std::vector<fuchsia::virtualization::BlockSpec>*(GuestConfig*)> mutable_field_;
};

std::unordered_map<std::string, std::unique_ptr<OptionHandler>> GetCmdlineOptionHanders() {
  std::unordered_map<std::string, std::unique_ptr<OptionHandler>> handlers;
  handlers.emplace("cmdline-add", std::make_unique<RepeatedOptionHandler<std::string>>(
                                      &GuestConfig::mutable_cmdline_add));
  handlers.emplace(
      "cpus", std::make_unique<NumCpusOptionHandler>(
                  &GuestConfig::has_cpus, &GuestConfig::mutable_cpus, zx_system_get_num_cpus()));
  handlers.emplace("interrupt", std::make_unique<RepeatedOptionHandler<uint32_t>>(
                                    &GuestConfig::mutable_interrupts));
  handlers.emplace("memory",
                   std::make_unique<RepeatedOptionHandler<fuchsia::virtualization::MemorySpec>>(
                       &GuestConfig::mutable_memory));
  handlers.emplace("default-net",
                   std::make_unique<BoolOptionHandler>(&GuestConfig::has_default_net,
                                                       &GuestConfig::mutable_default_net, true));
  handlers.emplace("virtio-balloon",
                   std::make_unique<BoolOptionHandler>(&GuestConfig::has_virtio_balloon,
                                                       &GuestConfig::mutable_virtio_balloon, true));
  handlers.emplace("virtio-console",
                   std::make_unique<BoolOptionHandler>(&GuestConfig::has_virtio_console,
                                                       &GuestConfig::mutable_virtio_console, true));
  handlers.emplace("virtio-gpu",
                   std::make_unique<BoolOptionHandler>(&GuestConfig::has_virtio_gpu,
                                                       &GuestConfig::mutable_virtio_gpu, true));
  handlers.emplace("virtio-rng",
                   std::make_unique<BoolOptionHandler>(&GuestConfig::has_virtio_rng,
                                                       &GuestConfig::mutable_virtio_rng, true));
  handlers.emplace("virtio-vsock",
                   std::make_unique<BoolOptionHandler>(&GuestConfig::has_virtio_vsock,
                                                       &GuestConfig::mutable_virtio_vsock, true));
  return handlers;
}

std::unordered_map<std::string, std::unique_ptr<OptionHandler>> GetAllOptionHandlers(
    OpenAt open_at) {
  auto handlers = GetCmdlineOptionHanders();
  handlers.emplace("block",
                   std::make_unique<RepeatedOptionHandler<fuchsia::virtualization::BlockSpec>>(
                       open_at.share(), &GuestConfig::mutable_block_devices));
  handlers.emplace("cmdline", std::make_unique<StringOptionHandler>(&GuestConfig::has_cmdline,
                                                                    &GuestConfig::mutable_cmdline));
  handlers.emplace("dtb-overlay", std::make_unique<FileOptionHandler>(
                                      open_at.share(), &GuestConfig::has_dtb_overlay,
                                      &GuestConfig::mutable_dtb_overlay));
  handlers.emplace(
      "linux", std::make_unique<KernelOptionHandler>(
                   open_at.share(), &GuestConfig::has_kernel, &GuestConfig::mutable_kernel,
                   &GuestConfig::mutable_kernel_type, fuchsia::virtualization::KernelType::LINUX));
  handlers.emplace("ramdisk",
                   std::make_unique<FileOptionHandler>(open_at.share(), &GuestConfig::has_ramdisk,
                                                       &GuestConfig::mutable_ramdisk));
  handlers.emplace("zircon", std::make_unique<KernelOptionHandler>(
                                 open_at.share(), &GuestConfig::has_kernel,
                                 &GuestConfig::mutable_kernel, &GuestConfig::mutable_kernel_type,
                                 fuchsia::virtualization::KernelType::ZIRCON));
  return handlers;
}

}  // namespace

void PrintCommandLineUsage(const char* program_name) {
  // clang-format off
  std::cerr << "usage: " << program_name << " [OPTIONS]\n";
  std::cerr << "\n";
  std::cerr << "OPTIONS:\n";
  std::cerr << "\t--cmdline-add=[string]  Adds 'string' to the existing kernel command line.\n";
  std::cerr << "\t--cpus=[number]         Number of virtual CPUs available to the guest\n";
  std::cerr << "\t--default-net           Enable a default net device (defaults to true)\n";
  std::cerr << "\t--memory=[bytes]        Allocate 'bytes' of memory for the guest.\n";
  std::cerr << "\t                        The suffixes 'k', 'M', and 'G' are accepted\n";
  std::cerr << "\t                        (default " << kDefaultMemory << " bytes)\n";
  std::cerr << "\t--interrupt=[spec]      Adds a hardware interrupt mapping to the guest\n";
  std::cerr << "\t--virtio-balloon        Enable virtio-balloon (default)\n";
  std::cerr << "\t--virtio-console        Enable virtio-console (default)\n";
  std::cerr << "\t--virtio-gpu            Enable virtio-gpu and virtio-input (default)\n";
  std::cerr << "\t--virtio-rng            Enable virtio-rng (default)\n";
  std::cerr << "\t--virtio-vsock          Enable virtio-vsock (default)\n";
  std::cerr << "\n";
  std::cerr << "NET SPEC\n";
  std::cerr << "\n";
  std::cerr << " Net devices can be specified by MAC address. Each --net argument specifies an\n";
  std::cerr << " additional device.\n";
  std::cerr << "\n";
  std::cerr << " Ex:\n";
  std::cerr << "    --net=02:1a:11:00:00:00\n";
  std::cerr << "\n";
  std::cerr << " By default the guest is configured with one net device with the MAC address in\n";
  std::cerr << " the example above. To remove the default device pass --default-net=false.\n";
  std::cerr << "\n";
  // clang-format on
}

void SetDefaults(GuestConfig* cfg) {
  if (!cfg->has_memory()) {
    cfg->mutable_memory()->push_back({.size = kDefaultMemory});
  }

  for (const auto& [name, handler] : GetCmdlineOptionHanders()) {
    handler->MaybeSetDefault(cfg);
  }

  if (cfg->default_net()) {
    cfg->mutable_net_devices()->push_back({
        .mac_address = kGuestMacAddress,
        // TODO(https://fxbug.dev/67566): Enable once bridging is fixed.
        .enable_bridge = false,
    });
  }
}

zx_status_t ParseArguments(int argc, const char** argv, fuchsia::virtualization::GuestConfig* cfg) {
  fxl::CommandLine cl = fxl::CommandLineFromArgcArgv(argc, argv);

  if (cl.positional_args().size() > 0) {
    FX_LOGS(ERROR) << "Unknown positional option: " << cl.positional_args()[0];
    return ZX_ERR_INVALID_ARGS;
  }

  auto handlers = GetCmdlineOptionHanders();
  for (const fxl::CommandLine::Option& option : cl.options()) {
    auto entry = handlers.find(option.name);
    if (entry == handlers.end()) {
      FX_LOGS(ERROR) << "Unknown option --" << option.name;
      return ZX_ERR_INVALID_ARGS;
    }
    auto status = entry->second->Set(cfg, option.name, option.value, /* override= */ true);
    if (status != ZX_OK) {
      return ZX_ERR_INVALID_ARGS;
    }
  }
  return ZX_OK;
}

zx_status_t ParseConfig(const std::string& data, OpenAt open_at, GuestConfig* cfg) {
  rapidjson::Document document;
  document.Parse(data);
  if (!document.IsObject()) {
    return ZX_ERR_INVALID_ARGS;
  }

  auto opts = GetAllOptionHandlers(std::move(open_at));
  for (auto& member : document.GetObject()) {
    auto entry = opts.find(member.name.GetString());
    if (entry == opts.end()) {
      FX_LOGS(ERROR) << "Unknown field in configuration object: " << member.name.GetString();
      return ZX_ERR_INVALID_ARGS;
    }

    // For string members, invoke the handler directly on the value.
    if (member.value.IsString()) {
      zx_status_t status = entry->second->Set(cfg, member.name.GetString(),
                                              member.value.GetString(), /* override= */ false);
      if (status != ZX_OK) {
        return ZX_ERR_INVALID_ARGS;
      }
      continue;
    }

    // For array members, invoke the handler on each value in the array.
    if (member.value.IsArray()) {
      for (auto& array_member : member.value.GetArray()) {
        if (!array_member.IsString()) {
          FX_LOGS(ERROR) << "Array entry has incorect type, expected string: "
                         << member.name.GetString();
          return ZX_ERR_INVALID_ARGS;
        }
        zx_status_t status = entry->second->Set(cfg, member.name.GetString(),
                                                array_member.GetString(), /* override= */ true);
        if (status != ZX_OK) {
          return ZX_ERR_INVALID_ARGS;
        }
      }
      continue;
    }
    FX_LOGS(ERROR) << "Field has incorrect type, expected string or array: "
                   << member.name.GetString();
    return ZX_ERR_INVALID_ARGS;
  }

  return ZX_OK;
}

}  // namespace guest_config
