// Copyright 2017 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 <assert.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#ifndef _ALL_SOURCE
#define _ALL_SOURCE  // Enables thrd_create_with_name in <threads.h>.
#endif
#include <lib/async-loop/default.h>
#include <lib/async-loop/loop.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/io.h>
#include <lib/fdio/spawn.h>
#include <lib/fdio/unsafe.h>
#include <lib/zircon-internal/paths.h>
#include <threads.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

#include "fuchsia/loader-wrapper.h"
#include "includes.h"
#include "misc.h"
#include "openbsd-compat/bsd-misc.h"
#include "xmalloc.h"

static async_loop_t* loop;
static thrd_t loop_thread;
static loader_service_t* ldsvc;
static zx_handle_t container_job = ZX_HANDLE_INVALID;

static void cleanup_container_job(void) {
  if (container_job == ZX_HANDLE_INVALID) {
    return;
  }

  if (zx_task_kill(container_job) != ZX_OK) {
    fprintf(stderr, "warning: failed to kill container job on shutdown\n");
    return;
  }

  zx_time_t now = zx_clock_get_monotonic();
  zx_signals_t observed;
  if (zx_object_wait_one(container_job, ZX_JOB_TERMINATED, now + ZX_SEC(5), &observed) ==
      ZX_ERR_TIMED_OUT) {
    fprintf(stderr, "warning: timed out waiting for container job to terminate\n");
  }
}

static zx_handle_t get_container_job(void) {
  if (container_job != ZX_HANDLE_INVALID) {
    return container_job;
  }

  if (zx_job_create(zx_job_default(), 0, &container_job) != ZX_OK) {
    fprintf(stderr, "fatal: failed to create job to contain ssh processes\n");
    exit(1);
  }

  atexit(cleanup_container_job);

  return container_job;
}

async_dispatcher_t* get_async() { return async_loop_get_dispatcher(loop); }

void fuchsia_init_async(void) {
  zx_status_t status;
  status = async_loop_create(&kAsyncLoopConfigNoAttachToCurrentThread, &loop);
  if (status != ZX_OK) {
    fprintf(stderr, "fatal: failed to create async loop\n");
    exit(1);
  }

  status = async_loop_start_thread(loop, "sshd-async-loop", &loop_thread);
  if (status != ZX_OK) {
    fprintf(stderr, "fatal: failed to create async loop\n");
    exit(1);
  }

  int boot_lib_dir;
  status = fdio_open_fd("/boot/lib", lib_dir_open_flags(), &boot_lib_dir);
  if (status != ZX_OK) {
    fprintf(stderr, "fatal: failed to open /boot/lib: %d\n", status);
    exit(1);
  }

  if ((status = loader_service_create(get_async(), boot_lib_dir, "openssh", &ldsvc)) != ZX_OK) {
    fprintf(stderr, "failed to create loader service: %s\n", zx_status_get_string(status));
    exit(1);
  }
}

int chroot(const char* path) { return -1; }

typedef struct Authctxt Authctxt;

int sys_auth_passwd(Authctxt* authctxt, const char* password) {
  // Password authentication always fails.
  return 0;
}

#define USERNAME_MAX 32
static char username[USERNAME_MAX + 1] = {'f', 'u', 'c', 'h', 's', 'i', 'a', 0};
static struct passwd static_passwd = {
    .pw_name = username,
    .pw_passwd = "",
    .pw_uid = 23,  // matches ZX_UID
    .pw_gid = 23,
    .pw_gecos = "Fuchsia",
    .pw_dir = "/",
    .pw_shell = ZX_SHELL_DEFAULT,
};

struct passwd* getpwnam(const char* name) {
  size_t len = strlen(name);
  if (len > USERNAME_MAX) {
    errno = EINVAL;
    return NULL;
  }
  strncpy(username, name, len);
  username[len] = 0;
  return &static_passwd;
}

struct passwd* getpwuid(uid_t uid) { return &static_passwd; }

#define ARGV_MAX 256

typedef struct {
  enum { UNUSED, RUNNING, STOPPED } state;
  int exit_code;
} Child;

#define BASE_PID 2
#define NUM_CHILDREN 256
static Child children[NUM_CHILDREN];

static Child* get_child(pid_t pid) {
  assert(pid - BASE_PID < NUM_CHILDREN);
  assert(pid >= BASE_PID);
  return &children[pid - BASE_PID];
}

static pid_t get_unused_pid() {
  for (int i = 0; i < NUM_CHILDREN; i++) {
    if (children[i].state == UNUSED) {
      return i + BASE_PID;
    }
  }
  fprintf(stderr, "Can't allocate new pid.\n");
  exit(1);
}

static volatile sshsig_t sigchld_handler = SIG_IGN;

typedef struct {
  pid_t pid;
  zx_handle_t in, out, err;
  char* command;
  char** env;
} LaunchRequest;

// make_launch_request copies command, but takes ownership over env.
LaunchRequest* make_launch_request(const char* command, char** env, int in, int out, int err) {
  LaunchRequest* lr = xmalloc(sizeof(LaunchRequest));
  lr->pid = get_unused_pid();
  if (command == NULL) {
    lr->command = NULL;
  } else {
    lr->command = xmalloc(strlen(command) + 1);
    strcpy(lr->command, command);
  }

  lr->env = env;

  /*
   * ssh's session.c will close out our file descriptors, as it is expecting a fork() to occur, so
   * we can't use these fd's "some time later" in the child thread. Clone handles from the fd's now
   * and use those on the thread. fdio_fd_transfer cannot be used because that immediately consumes
   * and closes the fd, which results in racy behavior since session.c will still also close these
   * fd numbers, but they may have been reused by other threads by then.
   */
  zx_status_t status;
  if ((status = fdio_fd_clone(in, &lr->in)) != ZX_OK) {
    fprintf(stderr, "failed to clone in fd %d\n", in);
  }
  if ((status = fdio_fd_clone(out, &lr->out)) != ZX_OK) {
    fprintf(stderr, "failed to clone out fd %d\n", out);
  }
  if ((status = fdio_fd_clone(err, &lr->err)) != ZX_OK) {
    fprintf(stderr, "failed to clone err fd %d\n", err);
  }
  return lr;
}

// free_env free's a **env as produced by session.c
void free_env(char** env) {
  char** envf = env;
  while (*envf != NULL) {
    free(*envf++);
  }
  free(env);
}

// free_launch_request frees a LaunchRequest. It frees command and env. It does
// not modify child, and does not close any of the handles.
void free_launch_request(LaunchRequest* lr) {
  free(lr->command);
  free_env(lr->env);
  free(lr);
}

static zx_status_t spawn_launch_request(LaunchRequest* lr, zx_handle_t* proc, char* err_msg) {
  const char* command = lr->command;
  char** env = lr->env;

  // TODO(fxbug.dev/42121054): replace most of this with a "shell runner" instead
  const char* argv[ARGV_MAX];
  int argc = 1;
  argv[0] = ZX_SHELL_DEFAULT;
  if (command) {
    argv[argc++] = "-c";
    argv[argc++] = command;
  } else {
    command = argv[0];
  }
  argv[argc] = NULL;

  zx_status_t status;
  zx_handle_t ldsvc_hnd;
  if ((status = loader_service_connect(ldsvc, &ldsvc_hnd)) != ZX_OK) {
    fprintf(stderr, "failed to connect to loader service: %s\n", zx_status_get_string(status));
    exit(1);
  }

  fdio_spawn_action_t actions[4] = {
      {
          .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
          .h = {.id = PA_LDSVC_LOADER, .handle = ldsvc_hnd},
      },
      {
          .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
          .h = {.id = PA_HND(PA_FD, STDIN_FILENO), .handle = lr->in},
      },
      {
          .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
          .h = {.id = PA_HND(PA_FD, STDOUT_FILENO), .handle = lr->out},
      },
      {
          .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
          .h = {.id = PA_HND(PA_FD, STDERR_FILENO), .handle = lr->err},
      },
  };

  uint32_t flags = FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_CLONE_UTC_CLOCK;
  return fdio_spawn_etc(get_container_job(), flags, argv[0], argv, (const char* const*)env, 4,
                        actions, proc, err_msg);
}

static int child_thread_func(void* voidp) {
  thrd_detach(thrd_current());

  Child* child = get_child(((LaunchRequest*)voidp)->pid);
  zx_handle_t proc;

  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

  zx_status_t status = spawn_launch_request(voidp, &proc, err_msg);
  free_launch_request(voidp);

  if (status < 0) {
    fprintf(stderr, "error from fdio_spawn_etc: %s\n", err_msg);
    fprintf(stderr, " status=%d (%s)\n", status, zx_status_get_string(status));
    exit(1);
  }

  zx_signals_t observed;
  zx_object_wait_one(proc, ZX_PROCESS_TERMINATED, ZX_TIME_INFINITE, &observed);

  zx_info_process_t info;
  size_t actual;
  zx_object_get_info(proc, ZX_INFO_PROCESS, &info, sizeof(info), &actual, NULL);

  child->state = STOPPED;
  child->exit_code = info.return_code;

  sshsig_t handler = sigchld_handler;
  if (handler == SIG_IGN || handler == SIG_DFL) {
    // Don't call a handler
  } else {
    handler(SIGCHLD);
  }

  zx_handle_close(proc);
  return 0;
}

// Note: **env is consumed by this function and will be freed.
pid_t fuchsia_launch_child(const char* command, char** env, int in, int out, int err) {
  LaunchRequest* lr = make_launch_request(command, env, in, out, err);
  pid_t pid = lr->pid;
  get_child(pid)->state = RUNNING;

  thrd_t child_thread;
  if (thrd_create_with_name(&child_thread, child_thread_func, (void*)lr, "child-waiter") != 0) {
    fprintf(stderr, "Failed to create process spawn thread: %s\n", strerror(errno));
    exit(1);
  }

  return pid;
}

sshsig_t ssh_signal(int signum, sshsig_t handler) {
  if (signum == SIGCHLD) {
    sigchld_handler = handler;
  }
  // Ignore all non-SIGCHLD requests
  return handler;
}

pid_t waitpid(pid_t pid, int* status, int options) {
  if (pid == -1 || pid == 0) {
    // Find an exited process.
    for (pid = BASE_PID; pid < BASE_PID + NUM_CHILDREN; pid++) {
      if (get_child(pid)->state == STOPPED) {
        return waitpid(pid, status, options);
      }
    }
    if (options & WNOHANG) {
      return 0;
    } else {
      fprintf(stderr, "No child pids waiting for wait.\n");
      exit(1);
    }
  }

  Child* child = get_child(pid);
  if (child->state != STOPPED) {
    fprintf(stderr, "Child with pid %d isn't stopped.\n", pid);
    exit(1);
  }

  if (status) {
    // Make a status that can be parsed by WIFEXITED/WEXITSTATUS/etc.
    *status = (0xFF & child->exit_code) << 8;
  }
  child->state = UNUSED;

  return pid;
}
