// 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 <stdio.h>
#include <unistd.h>

#include <iostream>
#include <vector>

#include <lib/fdio/spawn.h>
#include <lib/fxl/arraysize.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/strings/string_printf.h>
#include <lib/zx/job.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/processargs.h>

// ProcessSpawner is a simple utility that waits for user input on stdin and
// creates a new process when anything that doens't say "exit" in it is entered.
//
// This is useful for debugging process attaching and similar functionality.

namespace {

uint64_t GetKoidForHandle(zx_handle_t handle) {
  zx_info_handle_basic_t info;
  zx_status_t res = zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info,
                                       sizeof(info), NULL, NULL);
  if (res != ZX_OK)
    return 0;
  return static_cast<uint64_t>(info.koid);
}

zx_status_t LaunchProcess(zx_handle_t job, const std::vector<const char*>& argv,
                          const char* name, int outfd, zx_handle_t* proc) {
  std::vector<const char*> normalized_argv = argv;
  normalized_argv.push_back(nullptr);

  fdio_spawn_action_t actions[] = {
      {.action = FDIO_SPAWN_ACTION_CLONE_FD,
       .fd = {.local_fd = outfd, .target_fd = STDOUT_FILENO}},
      {.action = FDIO_SPAWN_ACTION_CLONE_FD,
       .fd = {.local_fd = STDIN_FILENO, .target_fd = STDIN_FILENO}},
      {.action = FDIO_SPAWN_ACTION_CLONE_FD,
       .fd = {.local_fd = STDERR_FILENO, .target_fd = STDERR_FILENO}},
      {.action = FDIO_SPAWN_ACTION_SET_NAME, .name = {.data = name}}};
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  zx_status_t status =
      fdio_spawn_etc(job, FDIO_SPAWN_CLONE_ALL, normalized_argv.front(),
                     normalized_argv.data(), nullptr, arraysize(actions),
                     actions, proc, err_msg);
  return status;
}

}  // namespace

const char kBinaryPath[] =
    "/pkgfs/packages/debug_agent_tests/0/bin/process_loop";

int main() {
  zx_handle_t default_job = zx_job_default();
  zx_handle_t child_job;
  if (zx_status_t status = zx_job_create(default_job, 0u, &child_job);
      status != ZX_OK) {
    FXL_LOG(ERROR) << "Could not create a child job.";
    exit(1);
  }

  FXL_LOG(INFO) << "Parent job: " << GetKoidForHandle(default_job)
                << ", Created job: " << GetKoidForHandle(child_job);

  // We're going to keep a list of the created processes.
  struct Process {
    std::string name;
    zx_handle_t proc_handle;
    zx_handle_t vmar_handle;
  };
  std::vector<Process> processes;

  FXL_LOG(INFO) << "Waiting for output.";
  std::vector<char> current_line;
  while (true) {
    char c = getc(stdin);
    printf("%c", c);
    fflush(stdout);

    // We acumulate characters to that the user can write exit if they want to
    // exit. Not a very good UI, but works for the testing purposes.
    if (c >= 'a' && c <= 'z') {
      current_line.push_back(c);
      continue;
    }
    current_line.push_back(0);

    // If the user wrote exit somewhere, we exit.
    std::string cmd(current_line.data());
    if (cmd.find("exit") != std::string::npos) {
      FXL_LOG(INFO) << "Found \"exit\" in the input. Exiting.";
      exit(0);
    }

    // Spawn a process the fdio way.
    int pipe_fds[2];
    if (pipe(pipe_fds) != 0) {
      FXL_LOG(ERROR) << "Could not create pipes!";
      exit(1);
    }

    FXL_LOG(INFO) << "Creating process.";
    Process process;
    process.name = fxl::StringPrintf("process-%lu", processes.size());
    zx_status_t status =
        LaunchProcess(child_job, {kBinaryPath}, process.name.data(),
                      pipe_fds[0], &process.proc_handle);
    if (status != ZX_OK) {
      FXL_LOG(ERROR) << "Could not create process " << process.name << ": "
                     << zx_status_get_string(status);
      exit(1);
    }

    FXL_LOG(INFO) << "Created process " << process.name
                  << " with KOID: " << GetKoidForHandle(process.proc_handle);
    processes.push_back(std::move(process));
    current_line.clear();
  }

  return 0;
}
