// Copyright 2020 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/bringup/bin/console-launcher/console_launcher.h"

#include <fcntl.h>
#include <fuchsia/boot/cpp/fidl.h>
#include <fuchsia/hardware/virtioconsole/llcpp/fidl.h>
#include <fuchsia/kernel/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/spawn.h>
#include <lib/fdio/unsafe.h>
#include <lib/fdio/watcher.h>
#include <lib/fit/defer.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/syslog/global.h>
#include <lib/zircon-internal/paths.h>
#include <zircon/compiler.h>

#include <fbl/algorithm.h>

namespace console_launcher {

namespace {

// Get the root job from the root job service.
zx_status_t GetRootJob(zx::job* root_job) {
  auto svc_dir = sys::ServiceDirectory::CreateFromNamespace();
  fuchsia::kernel::RootJobSyncPtr root_job_ptr;
  zx_status_t status = svc_dir->Connect(root_job_ptr.NewRequest());
  if (status != ZX_OK) {
    return status;
  }
  return root_job_ptr->Get(root_job);
}

// Wait for the requested file.  Its parent directory must exist.
zx_status_t WaitForFile(const char* path, zx::time deadline) {
  char path_copy[PATH_MAX];
  if (strlen(path) >= PATH_MAX) {
    return ZX_ERR_INVALID_ARGS;
  }
  strcpy(path_copy, path);

  char* last_slash = strrchr(path_copy, '/');
  // Waiting on the root of the fs or paths with no slashes is not supported by this function
  if (last_slash == path_copy || last_slash == nullptr) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  last_slash[0] = 0;
  char* dirname = path_copy;
  char* basename = last_slash + 1;

  auto watch_func = [](int dirfd, int event, const char* fn, void* cookie) -> zx_status_t {
    auto basename = static_cast<const char*>(cookie);
    if (event != WATCH_EVENT_ADD_FILE) {
      return ZX_OK;
    }
    if (!strcmp(fn, basename)) {
      return ZX_ERR_STOP;
    }
    return ZX_OK;
  };

  fbl::unique_fd dirfd(open(dirname, O_RDONLY));
  if (!dirfd.is_valid()) {
    return ZX_ERR_INVALID_ARGS;
  }
  zx_status_t status = fdio_watch_directory(dirfd.get(), watch_func, deadline.get(),
                                            reinterpret_cast<void*>(basename));
  if (status == ZX_ERR_STOP) {
    return ZX_OK;
  }
  return status;
}

}  // namespace

zx::status<ConsoleLauncher> ConsoleLauncher::Create() {
  ConsoleLauncher launcher;

  zx::job root_job;
  // TODO(fxbug.dev/33957): Remove all uses of the root job.
  zx_status_t status = GetRootJob(&root_job);
  if (status != ZX_OK) {
    FX_LOGF(ERROR, "Failed to get root job: %s", zx_status_get_string(status));
    return zx::error(status);
  }
  status = zx::job::create(root_job, 0u, &launcher.shell_job_);
  if (status != ZX_OK) {
    FX_LOGF(ERROR, "Failed to create shell_job: %s", zx_status_get_string(status));
    return zx::error(status);
  }
  status = launcher.shell_job_.set_property(ZX_PROP_NAME, "zircon-shell", 16);
  if (status != ZX_OK) {
    FX_LOGF(ERROR, "Failed to set shell_job job name: %s", zx_status_get_string(status));
    return zx::error(status);
  }

  return zx::ok(std::move(launcher));
}

std::optional<Arguments> GetArguments(fidl::WireSyncClient<fuchsia_boot::Arguments>* client) {
  Arguments ret;

  fuchsia_boot::wire::BoolPair bool_keys[]{
      {fidl::StringView{"console.shell"}, false},
      {fidl::StringView{"kernel.shell"}, false},
      {fidl::StringView{"console.is_virtio"}, false},
      {fidl::StringView{"devmgr.log-to-debuglog"}, false},
  };
  auto bool_resp =
      client->GetBools(fidl::VectorView<fuchsia_boot::wire::BoolPair>::FromExternal(bool_keys));
  if (!bool_resp.ok()) {
    printf("console-launcher: failed to get boot bools\n");
    return std::nullopt;
  }

  ret.run_shell = bool_resp->values[0];
  // If the kernel console is running a shell we can't launch our own shell.
  ret.run_shell = ret.run_shell & !bool_resp->values[1];
  ret.is_virtio = bool_resp->values[2];
  ret.log_to_debuglog = bool_resp->values[3];

  fidl::StringView vars[]{
      fidl::StringView{"TERM"},
      fidl::StringView{"console.path"},
      fidl::StringView{"zircon.autorun.boot"},
      fidl::StringView{"zircon.autorun.system"},
  };
  auto resp = client->GetStrings(fidl::VectorView<fidl::StringView>::FromExternal(vars));
  if (!resp.ok()) {
    printf("console-launcher: failed to get console path\n");
    return std::nullopt;
  }

  if (resp->values[0].is_null()) {
    ret.term += "uart";
  } else {
    ret.term += std::string{resp->values[0].data(), resp->values[0].size()};
  }
  if (!resp->values[1].is_null()) {
    ret.device = std::string{resp->values[1].data(), resp->values[1].size()};
  }
  if (!resp->values[2].is_null()) {
    ret.autorun_boot = std::string{resp->values[2].data(), resp->values[2].size()};
  }
  if (!resp->values[3].is_null()) {
    ret.autorun_system = std::string{resp->values[3].data(), resp->values[3].size()};
  }

  return ret;
}

std::optional<fbl::unique_fd> ConsoleLauncher::GetVirtioFd(const Arguments& args,
                                                           fbl::unique_fd device_fd) {
  zx::channel virtio_channel;
  zx_status_t status =
      fdio_get_service_handle(device_fd.release(), virtio_channel.reset_and_get_address());
  if (status != ZX_OK) {
    printf("console-launcher: failed to get console handle '%s'\n", args.device.data());
    return std::nullopt;
  }

  zx::channel local, remote;
  status = zx::channel::create(0, &local, &remote);
  if (status != ZX_OK) {
    printf("console-launcher: failed to create channel for console '%s'\n", args.device.data());
    return std::nullopt;
  }

  fidl::WireSyncClient<fuchsia_hardware_virtioconsole::Device> virtio_client(
      std::move(virtio_channel));
  virtio_client.GetChannel(std::move(remote));

  fdio_t* fdio;
  status = fdio_create(local.release(), &fdio);
  if (status != ZX_OK) {
    printf("console-launcher: failed to setup fdio for console '%s'\n", args.device.data());
    return std::nullopt;
  }

  fbl::unique_fd fd(fdio_bind_to_fd(fdio, -1, 3));
  if (!fd.is_valid()) {
    fdio_unsafe_release(fdio);
    printf("console-launcher: failed to transfer fdio for console '%s'\n", args.device.data());
    return std::nullopt;
  }

  return fd;
}

zx_status_t ConsoleLauncher::LaunchShell(const Arguments& args) {
  if (!args.run_shell) {
    FX_LOGS(INFO) << "console-launcher: disabled";
    return ZX_OK;
  }

  zx_status_t status = WaitForFile(args.device.data(), zx::time::infinite());
  if (status != ZX_OK) {
    FX_LOGS(INFO) << "console-launcher: failed to wait for console";
    printf("console-launcher: failed to wait for console '%s' (%s)\n", args.device.data(),
           zx_status_get_string(status));
    return status;
  }

  fbl::unique_fd fd(open(args.device.data(), O_RDWR));
  if (!fd.is_valid()) {
    printf("console-launcher: failed to open console '%s'\n", args.device.data());
    return ZX_ERR_INVALID_ARGS;
  }

  // TODO(fxbug.dev/33183): Clean this up once devhost stops speaking fuchsia.io.File
  // on behalf of drivers.  Once that happens, the virtio-console driver
  // should just speak that instead of this shim interface.
  if (args.is_virtio) {
    std::optional<fbl::unique_fd> result = GetVirtioFd(args, std::move(fd));
    if (!result) {
      return ZX_ERR_INTERNAL;
    }
    fd = std::move(*result);
  }

  const char* argv[] = {ZX_SHELL_DEFAULT, nullptr};
  const char* environ[] = {args.term.data(), nullptr};

  std::vector<fdio_spawn_action_t> actions;
  // Add an action to set the new process name.
  {
    fdio_spawn_action_t name = {};
    name.action = FDIO_SPAWN_ACTION_SET_NAME;
    name.name.data = "sh:console";
    actions.push_back(std::move(name));
  }

  // Get our current namespace so we can pass it to the shell process.
  fdio_flat_namespace_t* flat = nullptr;
  status = fdio_ns_export_root(&flat);
  if (status != ZX_OK) {
    return status;
  }
  auto free_flat = fit::defer([&flat]() { fdio_ns_free_flat_ns(flat); });

  // Go through each directory in our namespace and copy all of them except /system-delayed.
  for (size_t i = 0; i < flat->count; i++) {
    if (strcmp(flat->path[i], "/system-delayed") == 0) {
      continue;
    }
    fdio_spawn_action_t add_dir = {};
    add_dir.action = FDIO_SPAWN_ACTION_ADD_NS_ENTRY;
    add_dir.ns.handle = flat->handle[i];
    add_dir.ns.prefix = flat->path[i];
    actions.push_back(std::move(add_dir));
  }

  // Add an action to transfer the STDIO handle.
  {
    fdio_spawn_action_t stdio = {};
    stdio.action = FDIO_SPAWN_ACTION_TRANSFER_FD;
    stdio.fd = {.local_fd = fd.release(), .target_fd = FDIO_FLAG_USE_FOR_STDIO};
    actions.push_back(std::move(stdio));
  }

  uint32_t flags = FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_STDIO & ~FDIO_SPAWN_CLONE_NAMESPACE;

  FX_LOGF(INFO, nullptr, "Launching %s (%s)\n", argv[0], actions[0].name.data);
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  status = fdio_spawn_etc(shell_job_.get(), flags, argv[0], argv, environ, actions.size(),
                          actions.data(), shell_process_.reset_and_get_address(), err_msg);
  if (status != ZX_OK) {
    printf("console-launcher: failed to launch console shell: %s: %d (%s)\n", err_msg, status,
           zx_status_get_string(status));
    return status;
  }
  return ZX_OK;
}

zx_status_t ConsoleLauncher::WaitForShellExit() {
  zx_status_t status =
      shell_process_.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), nullptr);
  if (status != ZX_OK) {
    printf("console-launcher: failed to wait for console shell termination (%s)\n",
           zx_status_get_string(status));
    return status;
  }
  zx_info_process_v2_t proc_info;
  status =
      shell_process_.get_info(ZX_INFO_PROCESS_V2, &proc_info, sizeof(proc_info), nullptr, nullptr);
  if (status != ZX_OK) {
    printf("console-launcher: failed to determine console shell termination cause (%s)\n",
           zx_status_get_string(status));
    return status;
  }
  printf("console-launcher: console shell exited (started=%d exited=%d, return_code=%ld)\n",
         (proc_info.flags & ZX_INFO_PROCESS_FLAG_STARTED) != 0,
         (proc_info.flags & ZX_INFO_PROCESS_FLAG_EXITED) != 0, proc_info.return_code);
  return ZX_OK;
}

}  // namespace console_launcher
