// Copyright 2019 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/developer/forensics/exceptions/limbo_client/options.h"

#include <zircon/exception.h>
#include <zircon/status.h>

#include "src/developer/forensics/exceptions/limbo_client/limbo_client.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace forensics {
namespace exceptions {

namespace {

zx_status_t EnableLimbo(LimboClient*, const std::vector<const char*>&, std::ostream&);
zx_status_t DisableLimbo(LimboClient*, const std::vector<const char*>&, std::ostream&);
zx_status_t ListLimbo(LimboClient*, const std::vector<const char*>&, std::ostream&);
zx_status_t ReleaseFromLimbo(LimboClient*, const std::vector<const char*>&, std::ostream&);

struct Option {
  std::string name;
  std::string description;
  OptionFunction func = nullptr;
};

const Option kOptions[] = {
    {"enable", "Enable the process limbo. It will now begin to capture crashing processes.",
     EnableLimbo},
    {"disable", "Disable the process limbo. Will free any pending processes waiting in it.",
     DisableLimbo},
    {"list", "Lists the processes currently waiting on limbo. The limbo must be active.",
     ListLimbo},
    {"release",
     "Release a process from limbo. The limbo must be active. Usage: limbo release <pid>.",
     ReleaseFromLimbo},
};

void PrintUsage(std::ostream& os) {
  os << R"(Usage: limbo [--help] <option>

  The process limbo is a service that permits the system to suspend any processes that throws an
  exception (crash) for later processing/debugging. This CLI tool permits to query and modify the
  state of the limbo.

  Options:
    --help: Prints this message.
)";

  for (const Option& option : kOptions) {
    os << "    " << option.name << ": " << option.description << std::endl;
  }
}

// Actions Implementations -------------------------------------------------------------------------

zx_status_t EnableLimbo(LimboClient* limbo, const std::vector<const char*>& argv,
                        std::ostream& os) {
  if (limbo->active()) {
    os << "Limbo is already active." << std::endl;
    return ZX_OK;
  }

  if (zx_status_t status = limbo->SetActive(true); status != ZX_OK) {
    os << "Could not activate limbo: " << zx_status_get_string(status) << std::endl;
    return status;
  }

  os << "Activated the process limbo." << std::endl;
  return ZX_OK;
}

zx_status_t DisableLimbo(LimboClient* limbo, const std::vector<const char*>& argv,
                         std::ostream& os) {
  if (!limbo->active()) {
    os << "Limbo is already deactivated." << std::endl;
    return ZX_OK;
  }

  if (zx_status_t status = limbo->SetActive(false); status != ZX_OK) {
    os << "Could not deactivate limbo: " << zx_status_get_string(status) << std::endl;
    return status;
  }

  os << "Deactivated the process limbo. All contained processes have been freed." << std::endl;
  return ZX_OK;
}

zx_status_t ListLimbo(LimboClient* client, const std::vector<const char*>& argv, std::ostream& os) {
  if (!client->active()) {
    os << "Process limbo is not active." << std::endl;
    return ZX_OK;
  }

  std::vector<LimboClient::ProcessDescription> processes;
  if (zx_status_t status = client->ListProcesses(&processes); status != ZX_OK) {
    os << "Could not list the process limbo: " << zx_status_get_string(status) << std::endl;
    return status;
  }

  if (processes.empty()) {
    os << "No processes currently on limbo." << std::endl;
    return ZX_OK;
  }

  os << "Processes currently on limbo: " << std::endl;
  for (const auto& process : processes) {
    auto msg = fxl::StringPrintf("%s (pid: %lu), thread %s (tid: %lu) on exception: %s",
                                 process.process_name.c_str(), process.process_koid,
                                 process.thread_name.c_str(), process.thread_koid,
                                 zx_exception_get_string(process.exception));
    os << "- " << msg << std::endl;
  }

  return ZX_OK;
}

zx_status_t ReleaseFromLimbo(LimboClient* client, const std::vector<const char*>& argv,
                             std::ostream& os) {
  if (!client->active()) {
    os << "Process limbo is not active." << std::endl;
    return ZX_OK;
  }

  if (argv.size() != 3u) {
    os << "Release Usage: limbo release <pid>" << std::endl;
    return ZX_ERR_INVALID_ARGS;
  }

  uint64_t pid = std::atoll(argv[2]);
  if (pid == 0) {
    os << "Invalid pid " << argv[2] << std::endl;
    os << "Release Usage: limbo release <pid>" << std::endl;
    return ZX_ERR_INVALID_ARGS;
  }

  if (zx_status_t status = client->Release(pid); status != ZX_OK) {
    if (status == ZX_ERR_NOT_FOUND) {
      os << "Could not find pid: " << pid << std::endl;
    }

    return status;
  }

  os << "Successfully release process " << pid << " from limbo." << std::endl;
  return ZX_OK;
}

}  // namespace

OptionFunction ParseArgs(int argc, const char* argv[], std::ostream& os) {
  if (argc == 1 || std::string(argv[1]) == "--help") {
    PrintUsage(os);
    return nullptr;
  }

  for (const Option& option : kOptions) {
    if (option.name == argv[1])
      return option.func;
  }

  os << "Could not find option: " << argv[1] << std::endl;
  PrintUsage(os);
  return nullptr;
}

}  // namespace exceptions
}  // namespace forensics
