// 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 "fdio.h"

#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/fdio/spawn.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zircon-internal/paths.h>
#include <lib/zx/channel.h>
#include <lib/zx/debuglog.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/resource.h>
#include <lib/zx/vmo.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/log.h>

#include <iterator>
#include <utility>

#include <fbl/algorithm.h>
#include <fbl/array.h>
#include <fbl/vector.h>

namespace devmgr {

#define CHILD_JOB_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_MANAGE_JOB | ZX_RIGHT_MANAGE_PROCESS)

enum class FdioAction {
  AddNsEntry = 1,
  CloneDir = 2,
};

// clang-format off

static struct {
    const char* mount;
    const char* name;
    uint32_t flags;
    FdioAction action;
} FSTAB[] = {
    { "/svc",         "svc",         FS_SVC,        FdioAction::CloneDir },
    { "/data",        "data",        FS_DATA,       FdioAction::AddNsEntry },
    { "/blob",        "blobexec",    FS_BLOB_EXEC,  FdioAction::AddNsEntry },
    { "/svc_blobfs",  "svc_blobfs",  FS_SVC_BLOBFS, FdioAction::CloneDir },
};

// clang-format on

FsProvider::~FsProvider() {}

DevmgrLauncher::DevmgrLauncher(FsProvider* fs_provider) : fs_provider_(fs_provider) {}

zx_status_t DevmgrLauncher::LaunchWithLoader(const zx::job& job, const char* name,
                                             zx::vmo executable, zx::channel loader,
                                             const char* const* argv, const char** initial_envp,
                                             int stdiofd, const zx::resource& root_resource,
                                             const zx_handle_t* handles, const uint32_t* types,
                                             size_t hcount, zx::process* out_proc, uint32_t flags) {
  zx::job job_copy;
  zx_status_t status = job.duplicate(CHILD_JOB_RIGHTS, &job_copy);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "launch failed " << zx_status_get_string(status);
    return status;
  }

  zx::debuglog debuglog;
  if (stdiofd < 0) {
    if ((status = zx::debuglog::create(root_resource, 0, &debuglog) != ZX_OK)) {
      return status;
    }
  }

  uint32_t spawn_flags = FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_UTC_CLOCK;

  // Set up the environ for the new process
  fbl::Vector<const char*> env;
  if (getenv(LDSO_TRACE_CMDLINE)) {
    env.push_back(LDSO_TRACE_ENV);
  }
  env.push_back(ZX_SHELL_ENV_PATH);
  while (initial_envp && initial_envp[0]) {
    env.push_back(*initial_envp++);
  }
  env.push_back(nullptr);

  fbl::Vector<fdio_spawn_action_t> actions;
  actions.reserve(3 + std::size(FSTAB) + hcount);

  actions.push_back((fdio_spawn_action_t){
      .action = FDIO_SPAWN_ACTION_SET_NAME,
      .name = {.data = name},
  });

  if (loader.is_valid()) {
    actions.push_back((fdio_spawn_action_t){
        .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
        .h = {.id = PA_HND(PA_LDSVC_LOADER, 0), .handle = loader.release()},
    });
  } else {
    spawn_flags |= FDIO_SPAWN_DEFAULT_LDSVC;
  }

  // create namespace based on FS_* flags
  for (unsigned n = 0; n < std::size(FSTAB); n++) {
    if (!(FSTAB[n].flags & flags)) {
      continue;
    }
    switch (FSTAB[n].action) {
      case FdioAction::AddNsEntry: {
        zx_handle_t h;
        if ((h = fs_provider_->CloneFs(FSTAB[n].name).release()) != ZX_HANDLE_INVALID) {
          actions.push_back((fdio_spawn_action_t){
              .action = FDIO_SPAWN_ACTION_ADD_NS_ENTRY,
              .ns = {.prefix = FSTAB[n].mount, .handle = h},
          });
        }
      } break;
      case FdioAction::CloneDir:
        actions.push_back((fdio_spawn_action_t){
            .action = FDIO_SPAWN_ACTION_CLONE_DIR,
            .dir = {.prefix = FSTAB[n].mount},
        });
        break;
      default:
        __UNREACHABLE;
    }
  }

  if (debuglog.is_valid()) {
    actions.push_back((fdio_spawn_action_t){
        .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
        .h = {.id = PA_HND(PA_FD, FDIO_FLAG_USE_FOR_STDIO | 0), .handle = debuglog.release()},
    });
  } else {
    actions.push_back((fdio_spawn_action_t){
        .action = FDIO_SPAWN_ACTION_TRANSFER_FD,
        .fd = {.local_fd = stdiofd, .target_fd = FDIO_FLAG_USE_FOR_STDIO | 0},
    });
  }

  for (size_t i = 0; i < hcount; ++i) {
    actions.push_back((fdio_spawn_action_t){
        .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
        .h = {.id = types[i], .handle = handles[i]},
    });
  }

  zx::process proc;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  if (executable.is_valid()) {
    status = fdio_spawn_vmo(job_copy.get(), spawn_flags, executable.release(), argv, env.data(),
                            actions.size(), actions.data(), proc.reset_and_get_address(), err_msg);
  } else {
    status = fdio_spawn_etc(job_copy.get(), spawn_flags, argv[0], argv, env.data(), actions.size(),
                            actions.data(), proc.reset_and_get_address(), err_msg);
  }
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "spawn " << argv[0] << " (" << name << ") failed: " << err_msg << ": "
                   << status;
    return status;
  }
  FX_LOGS(INFO) << "launch " << argv[0] << " (" << name << ") OK";
  if (out_proc != nullptr) {
    *out_proc = std::move(proc);
  }
  return ZX_OK;
}

zx_status_t DevmgrLauncher::Launch(const zx::job& job, const char* name, const char* const* argv,
                                   const char** initial_envp, int stdiofd,
                                   const zx::resource& root_resource, const zx_handle_t* handles,
                                   const uint32_t* types, size_t hcount, zx::process* out_proc,
                                   uint32_t flags) {
  return LaunchWithLoader(job, name, zx::vmo(), zx::channel(), argv, initial_envp, stdiofd,
                          root_resource, handles, types, hcount, out_proc, flags);
}

ArgumentVector ArgumentVector::FromCmdline(const char* cmdline) {
  ArgumentVector argv;
  const size_t cmdline_len = strlen(cmdline) + 1;
  argv.raw_bytes_.reset(new char[cmdline_len]);
  memcpy(argv.raw_bytes_.get(), cmdline, cmdline_len);

  // Get the full commandline by splitting on '+'.
  size_t argc = 0;
  char* token;
  char* rest = argv.raw_bytes_.get();
  while (argc < std::size(argv.argv_) && (token = strtok_r(rest, "+", &rest))) {
    argv.argv_[argc++] = token;
  }
  argv.argv_[argc] = nullptr;
  return argv;
}

std::ostream& operator<<(std::ostream& stream, const ArgumentVector& arguments) {
  const char* const* argv = arguments.argv();
  const char* prefix = "'";
  for (const char* arg = *argv; arg != nullptr; ++argv, arg = *argv) {
    stream << prefix << *argv << "'";
    prefix = " '";
  }
  return stream;
}

}  // namespace devmgr
