// Copyright 2016 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 <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include "garnet/lib/inferior_control/process.h"
#include "lib/fsl/handles/object_info.h"
#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/log_settings_command_line.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/string_number_conversions.h"

#include "server.h"

namespace {

constexpr char kUsageString[] =
    "Usage: debugserver [options] port [program [args...]]\n"
    "       debugserver [options] [--attach=pid] port\n"
    "\n"
    "  port    - TCP port\n"
    "  program - the path to the executable to run\n"
    "  pid     - process id (koid) of the process to attach to\n"
    "\n"
    "Note that only one of program or --attach=pid may be specified.\n"
    "\n"
    "e.g. debugserver 2345 /path/to/executable\n"
    "\n"
    "Options:\n"
    "  --help             show this help message\n"
    "  --verbose[=level]  set debug verbosity level\n"
    "  --quiet[=level]    set quietness level (opposite of verbose)\n"
    "\n"
    "--verbose=<level> : sets |min_log_level| to -level\n"
    "--quiet=<level>   : sets |min_log_level| to +level\n"
    "Quiet supersedes verbose if both are specified.\n"
    "Defined log levels:\n"
    "-n - verbosity level n\n"
    " 0 - INFO - this is the default level\n"
    " 1 - WARNING\n"
    " 2 - ERROR\n"
    " 3 - FATAL\n"
    "Note that negative log levels mean more verbosity.\n";

void PrintUsageString() { std::cout << kUsageString << std::endl; }

}  // namespace

int main(int argc, char* argv[]) {
  fxl::CommandLine cl = fxl::CommandLineFromArgcArgv(argc, argv);

  if (cl.HasOption("help", nullptr)) {
    PrintUsageString();
    return EXIT_SUCCESS;
  }
  if (cl.positional_args().empty()) {
    PrintUsageString();
    return EXIT_FAILURE;
  }

  if (!fxl::SetLogSettingsFromCommandLine(cl))
    return EXIT_FAILURE;

  std::string attach_pid_str;
  zx_koid_t attach_pid = ZX_KOID_INVALID;
  if (cl.GetOptionValue("attach", &attach_pid_str)) {
    if (!fxl::StringToNumberWithError<zx_koid_t>(attach_pid_str, &attach_pid)) {
      FXL_LOG(ERROR) << "Not a valid process id: " << attach_pid_str;
      return EXIT_FAILURE;
    }
  }

  uint16_t port;
  if (!fxl::StringToNumberWithError<uint16_t>(cl.positional_args()[0], &port)) {
    FXL_LOG(ERROR) << "Not a valid port number: " << cl.positional_args()[0];
    return EXIT_FAILURE;
  }

  FXL_LOG(INFO) << "Starting server.";

  // Give this thread an identifiable name for debugging purposes.
  fsl::SetCurrentThreadName("server (main)");

  debugserver::RspServer server(
      port, attach_pid,
      debugger_utils::Argv{cl.positional_args().begin() + 1,
                           cl.positional_args().end()});

  auto inferior = new inferior_control::Process(&server, &server);

  // Are we passed a pid or a program?
  if (attach_pid != ZX_KOID_INVALID && !server.inferior_argv().empty()) {
    FXL_LOG(ERROR) << "Cannot specify both --attach=pid and a program";
    return EXIT_FAILURE;
  }

  // It's simpler to set the current process here since we don't support
  // multiple processes yet. If running a program, the process is not live yet
  // however, it does not exist to the kernel yet. Calling
  // Process::Initialize() is left to the vRun command.
  server.set_current_process(inferior);

  bool status = server.Run();
  if (!status) {
    FXL_LOG(ERROR) << "Server exited with error";
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
