// 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 <fuchsia/virtualization/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fit/function.h>
#include <lib/sys/cpp/component_context.h>

#include <iostream>
#include <optional>

#include "lib/sys/cpp/component_context.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "src/virtualization/bin/guest/balloon.h"
#include "src/virtualization/bin/guest/launch.h"
#include "src/virtualization/bin/guest/list.h"
#include "src/virtualization/bin/guest/serial.h"
#include "src/virtualization/bin/guest/socat.h"
#include "src/virtualization/bin/guest/vshc.h"
#include "src/virtualization/lib/guest_config/guest_config.h"

static void usage() {
  std::cerr << "Usage: guest <command> <package> <command-args>...\n"
            << "\n"
            << "Commands:\n"
            << "  balloon       <env_id> <cid> <num-pages>\n"
            << "  balloon-stats <env_id> <cid>\n"
            << "  launch        <package> <vmm-args>...\n"
            << "  list\n"
            << "  serial        <env_id> <cid>\n"
            << "  socat         <env_id> <cid> <port>\n"
            << "  socat-listen  <env_id> <host-port>\n"
            << "  vsh           [<env_id> [<cid> [<port>]]]\n";
}

template <class T>
static bool parse_number(const char* arg, const char* name, T* value,
                         fxl::Base base = fxl::Base::k10) {
  std::string_view arg_view(arg);
  if (!fxl::StringToNumberWithError(arg_view, value, base)) {
    std::cerr << "Invalid " << name << ": " << arg_view << "\n";
    return false;
  }
  return true;
}

static bool read_guest_cfg(int argc, const char** argv, fuchsia::virtualization::GuestConfig* cfg) {
  zx_status_t status = guest_config::ParseArguments(argc - 1, argv + 1, cfg);
  if (status != ZX_OK) {
    guest_config::PrintCommandLineUsage(argv[0]);
    std::cerr << "Invalid arguments\n";
    return false;
  }
  return true;
}

static bool parse_args(int argc, const char** argv, async::Loop* loop,
                       sys::ComponentContext* context, fit::closure* func) {
  if (argc < 1) {
    return false;
  }
  std::string_view cmd_view(argv[0]);
  if (cmd_view == "balloon" && argc == 4) {
    uint32_t env_id, cid, num_pages;
    if (!parse_number(argv[1], "environment ID", &env_id)) {
      return false;
    } else if (!parse_number(argv[2], "context ID", &cid)) {
      return false;
    } else if (!parse_number(argv[3], "number of pages", &num_pages)) {
      return false;
    }
    *func = [env_id, cid, num_pages, context]() {
      handle_balloon(env_id, cid, num_pages, context);
    };
  } else if (cmd_view == "balloon-stats" && argc == 3) {
    uint32_t env_id, cid;
    if (!parse_number(argv[1], "environment ID", &env_id)) {
      return false;
    } else if (!parse_number(argv[2], "context ID", &cid)) {
      return false;
    }
    *func = [env_id, cid, context]() { handle_balloon_stats(env_id, cid, context); };
  } else if (cmd_view == "launch" && argc >= 2) {
    *func = [argc, argv, loop, context]() mutable {
      fuchsia::virtualization::GuestConfig cfg;
      if (read_guest_cfg(argc, argv, &cfg)) {
        handle_launch(argc - 1, argv + 1, loop, std::move(cfg), context);
      }
    };
  } else if (cmd_view == "list") {
    *func = [context]() { handle_list(context); };
  } else if (cmd_view == "serial" && argc == 3) {
    uint32_t env_id, cid;
    if (!parse_number(argv[1], "environment ID", &env_id)) {
      return false;
    } else if (!parse_number(argv[2], "context ID", &cid)) {
      return false;
    }
    *func = [env_id, cid, loop, context]() { handle_serial(env_id, cid, loop, context); };
  } else if (cmd_view == "socat" && argc == 4) {
    uint32_t env_id, cid, port;
    if (!parse_number(argv[1], "environment ID", &env_id)) {
      return false;
    } else if (!parse_number(argv[2], "context ID", &cid)) {
      return false;
    } else if (!parse_number(argv[3], "port", &port)) {
      return false;
    }
    *func = [env_id, cid, port, loop, context]() {
      handle_socat_connect(env_id, cid, port, loop, context);
    };
  } else if (cmd_view == "socat-listen" && argc == 3) {
    uint32_t env_id, host_port;
    if (!parse_number(argv[1], "environment ID", &env_id)) {
      return false;
    } else if (!parse_number(argv[2], "host port", &host_port)) {
      return false;
    }
    *func = [env_id, host_port, loop, context]() {
      handle_socat_listen(env_id, host_port, loop, context);
    };
  } else if (cmd_view == "vsh" && (argc >= 1 && argc <= 4)) {
    std::optional<uint32_t> env_id, cid, port;

    bool success = true;
    switch (argc) {
      case 4:
        port = -1;
        success &= parse_number(argv[3], "port", &*port);
      case 3:
        cid = -1;
        success &= parse_number(argv[2], "context ID", &*cid);
      case 2:
        env_id = -1;
        success &= parse_number(argv[1], "environment ID", &*env_id);
      case 1:
        break;
      default:
        return false;
    }

    if (!success) {
      return false;
    }

    *func = [env_id, cid, port, loop, context]() { handle_vsh(env_id, cid, port, loop, context); };
  } else {
    return false;
  }
  return true;
}

int main(int argc, const char** argv) {
  fit::closure func;
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory();

  // This program might be called via an alias representing the vsh subcommand, e.g.
  // `guest vsh 0 3` vs `vsh 0 3`
  // Only if called using the long form, we must adjust argv for input to |parse_args|
  // so that argv[0] represents the subcommand name.
  if (std::string_view(argv[0]) == "guest") {
    argc--;
    argv++;
  }

  if (!parse_args(argc, argv, &loop, context.get(), &func)) {
    usage();
    return ZX_ERR_INVALID_ARGS;
  }

  func();
  return 0;
}
