// Copyright 2017 The Chromium OS 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 <sys/stat.h>
#include <sys/types.h>

#include <iostream>
#include <map>
#include <memory>
#include <string>

#include <base/command_line.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/version.h>
#include <brillo/flag_helper.h>
#include <brillo/process.h>
#include <brillo/syslog_logging.h>

#include "vm_tools/launcher/constants.h"
#include "vm_tools/launcher/crosvm.h"

using std::cerr;
using std::cout;
using std::endl;

namespace {

void Usage(const std::string& program, const std::string& subcommand) {
  if (subcommand == "run" || subcommand == "start") {
    cout << "Usage: " << program << " " << subcommand
         << " VM_NAME ([ --container=PATH ] | [ --rwcontainer=PATH ])\n"
         << "         [ --nfs=PATH ] [ --ssh ] [ --vm_path=PATH ]\n";

    if (subcommand == "run")
      cout << "Run a VM in the foreground with serial console.\n";
    else
      cout << "Start a headless VM. Returns once the VM has booted\n\n";

    cout
        << "Arguments: VM_NAME - An arbitrary name for the VM. Required. Must\n"
        << "                     not be 'all'.\n\n"
        << "Flags: --container=PATH - Optional container disk image to mount.\n"
        << "                          If not specified, the VM will not run a\n"
        << "                          container.\n"
        << "       --rwcontainer=PATH - Same as the --container flag, but the\n"
        << "                            disk image will be mounted read-write\n"
        << "       --nfs=PATH - Optional path to a directory to mount via NFS\n"
        << "       --ssh - Enable ssh in the VM. Only functional on VM test\n"
        << "               images.\n"
        << "       --vm_path=PATH - Optional path to a custom VM\n"
        << "                        kernel/rootfs.\n";

  } else if (subcommand == "stop") {
    cout << "Usage: " << program << " " << subcommand
         << " (VM_NAME | all) [ --force ]\n"
         << "Shut down a VM with the given name.\n\n"
         << "Arguments: (VM_NAME | all) - VM name to stop. 'all' will stop all "
         << "                             running VMs. \n\n";

  } else if (subcommand == "getname") {
    cout << "Usage: " << program << " " << subcommand << " PID\n"
         << "Print the name for a VM with a given PID to stdout.\n\n"
         << "Arguments: PID - PID to find a VM name for. \n";

  } else {
    cout << "Usage: " << program << " run     VM_NAME\n"
         << "       " << program << " start   VM_NAME\n"
         << "       " << program << " stop    (VM_NAME | all)\n"
         << "       " << program << " getname PID\n"
         << "       " << program << " help    SUBCOMMAND\n\n"
         << "Run `" << program
         << " help SUBCOMMAND` for specific usage and flags.\n";
  }
  exit(1);
}

// Get the path to the latest available cros-termina component.
base::FilePath GetLatestVMPath() {
  base::FilePath component_dir(vm_tools::launcher::kVmDefaultPath);
  base::FileEnumerator dir_enum(component_dir, false,
                                base::FileEnumerator::DIRECTORIES);

  base::Version latest_version("0");
  base::FilePath latest_path;

  for (base::FilePath path = dir_enum.Next();
       !path.empty();
       path = dir_enum.Next()) {
    base::Version version(path.BaseName().value());
    if (!version.IsValid())
      continue;

    if (version > latest_version) {
      latest_version = version;
      latest_path = path;
    }
  }

  return latest_path;
}

}  // namespace

int main(int argc, char** argv) {
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);
  base::CommandLine::Init(argc, argv);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();

  auto args = cl->GetArgs();

  if (args.size() < 2)
    Usage(cl->GetProgram().value(), "");
  else if (cl->HasSwitch("help"))
    Usage(cl->GetProgram().value(), args[1]);

  std::string subcommand = args[0];

  // TODO(smbarber): Make an init script do this.
  int rc = mkdir(vm_tools::launcher::kVmRuntimeDirectory, 0700);
  if (rc && errno != EEXIST) {
    PLOG(ERROR) << "Failed to create vm runtime directory";
    return 1;
  }

  // Handle run and start. Both have the same args, and only differ in
  // I/O and blocking.
  if (subcommand == "run" || subcommand == "start") {
    std::string vm_name = args[1];
    if (vm_name == "all") {
      cout << "'all' is reserved and cannot be used for a VM name\n";
      return 1;
    }

    base::FilePath nfs = cl->GetSwitchValuePath("nfs");

    base::FilePath vm_path = cl->GetSwitchValuePath("vm_path");
    if (vm_path.empty())
      vm_path = GetLatestVMPath();

    if (vm_path.empty()) {
      LOG(ERROR) << "No VM rootfs/kernel available to run";
      return 1;
    }

    base::FilePath container_disk = cl->GetSwitchValuePath("rwcontainer");
    bool rw_container = false;
    if (!container_disk.empty()) {
      rw_container = true;
    } else {
      container_disk = cl->GetSwitchValuePath("container");
    }

    bool ssh = cl->HasSwitch("ssh");

    base::FilePath kernel_path =
        vm_path.Append(vm_tools::launcher::kVmKernelName);
    base::FilePath rootfs_path =
        vm_path.Append(vm_tools::launcher::kVmRootfsName);

    auto crosvm = vm_tools::launcher::CrosVM::Create(vm_name, kernel_path,
                                                     rootfs_path, nfs);
    if (!crosvm)
      return 1;

    if (subcommand == "run") {
      if (!crosvm->Run(ssh, container_disk, rw_container))
        return 1;
    } else if (subcommand == "start") {
      if (!crosvm->Start(ssh, container_disk, rw_container)) {
        cout << "Failed to start VM '" << vm_name << "'\n";
        return 1;
      }
      cout << "VM '" << vm_name << "' started\n";
    }
  } else if (subcommand == "stop") {
    std::string vm_name = args[1];

    if (vm_name == "all") {
      bool all_vms_stopped = true;

      base::FileEnumerator file_enum(
          base::FilePath(vm_tools::launcher::kVmRuntimeDirectory),
          false,  // recursive
          base::FileEnumerator::DIRECTORIES);
      for (base::FilePath instance_dir = file_enum.Next();
           !instance_dir.empty(); instance_dir = file_enum.Next()) {
        std::string vm_name = instance_dir.BaseName().value();
        auto crosvm = vm_tools::launcher::CrosVM::Load(vm_name);
        if (!crosvm)
          return 1;

        if (!crosvm->Stop()) {
          cout << "Failed to stop VM '" << vm_name << "'\n";
          all_vms_stopped = false;
        }
        cout << "VM '" << vm_name << "' stopped\n";
      }
      return !all_vms_stopped;
    }

    auto crosvm = vm_tools::launcher::CrosVM::Load(vm_name);
    if (!crosvm)
      return 1;

    if (!crosvm->Stop()) {
      cout << "Failed to stop VM '" << vm_name << "'\n";
      return 1;
    }
    cout << "VM '" << vm_name << "' stopped\n";
  } else if (subcommand == "getname") {
    std::string pid_raw = args[1];
    pid_t pid;
    if (!base::StringToInt(args[1], &pid)) {
      cerr << "Couldn't parse '" << pid_raw << "' as a pid\n";
      return 1;
    }
    std::string vm_name;
    if (!vm_tools::launcher::CrosVM::GetNameForPid(pid, &vm_name)) {
      cerr << "No VM associated with " << pid << endl;
      return 1;
    }
    cout << vm_name << endl;
  } else {
    Usage(cl->GetProgram().value(), args[1]);
  }

  return 0;
}
