// 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>
#include <zircon/device/vfs.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/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

#include "fuchsia/loader-wrapper.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;

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",
                        ZX_FS_RIGHT_READABLE | ZX_FS_RIGHT_EXECUTABLE | ZX_FS_FLAG_DIRECTORY,
                        &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(CF-578): 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(ZX_HANDLE_INVALID, 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;
}

// This is a very inefficient way to emulate select() by creating a port, adding all of the fds
// of interest as async waits, and blocking until we get a port packet back.
// The callers of this (like serverloop) generally have a static set of fds they care about, so
// it'd be much more efficient for them to register async waits on a port object that persists
// across blocking calls.
int fuchsia_select(int nfds, void* readfds, void* writefds, void* exceptfds,
                   struct timeval* timeout) {
  if (exceptfds) {
    errno = EINVAL;
    return -1;
  }

  fd_set* readfds_fd_set = (fd_set*)readfds;
  fd_set* writefds_fd_set = (fd_set*)writefds;

  int ret = 0;
  zx_handle_t port = ZX_HANDLE_INVALID;
  fdio_t* ios[FD_SETSIZE] = {0};

  // Create a fresh port for this wait.
  zx_status_t st = zx_port_create(0, &port);

  if (st != ZX_OK) {
    fprintf(stderr, "Can't allocate new port.\n");
    errno = EINVAL;
    ret = -1;
    goto cleanup;
  }

  // Register port waits for file descriptors in the read and write sets.
  for (int fd = 0; fd < nfds; ++fd) {
    uint32_t events = 0;
    if (readfds_fd_set && FD_ISSET(fd, readfds_fd_set)) {
      events |= POLLIN;
    }
    if (writefds_fd_set && FD_ISSET(fd, writefds_fd_set)) {
      events |= POLLOUT;
    }
    if (!events)
      continue;

    fdio_t* io;
    // This acquires a reference to the fdio which is released in the cleanup path below.
    if ((io = fdio_unsafe_fd_to_io(fd)) == NULL) {
      errno = EBADF;
      ret = -1;
      goto cleanup;
    }
    ios[fd] = io;
    zx_handle_t h;
    zx_signals_t sigs;
    // Translate the poll-style events to fdio-specific signal bits to wait on.
    fdio_unsafe_wait_begin(io, events, &h, &sigs);
    if (h == ZX_HANDLE_INVALID) {
      errno = EBADF;
      ret = -1;
      goto cleanup;
    }
    uint64_t key = fd;
    st = zx_object_wait_async(h, port, key, sigs, ZX_WAIT_ASYNC_ONCE);
    if (st != ZX_OK) {
      fprintf(stderr, "Can't wait on object %d.\n", st);
      errno = EINVAL;
      ret = -1;
      goto cleanup;
    }
  }

  zx_time_t deadline = (timeout == NULL)
                           ? ZX_TIME_INFINITE
                           : zx_deadline_after(ZX_SEC(timeout->tv_sec) + ZX_USEC(timeout->tv_usec));

  for (;;) {
    zx_port_packet_t packet;
    st = zx_port_wait(port, deadline, &packet);

    // We expect zx_port_wait to return either ZX_ERR_TIMED_OUT if nothing happened, or ZX_OK
    // if at least one thing happened.
    if (st == ZX_OK) {
      if (packet.type != ZX_PKT_TYPE_SIGNAL_ONE) {
        fprintf(stderr, "Unexpected port packet type %u\n", packet.type);
        errno = EINVAL;
        ret = -1;
        goto cleanup;
      }
      // We've heard about an fd in the set we care about. Update the read/write
      // sets to reflect this information, then remove them from the set we are
      // listening to.
      int fd = (int)packet.key;
      uint32_t events = 0;
      fdio_t* io = ios[fd];
      if (!io) {
        fprintf(stderr, "Can't find fd for packet key %d.\n", fd);
        errno = EINVAL;
        ret = -1;
        goto cleanup;
      }
      // fdio_unsafe_wait_end translates the signals back to poll-style flags.
      fdio_unsafe_wait_end(io, packet.signal.observed, &events);
      if (readfds_fd_set && FD_ISSET(fd, readfds_fd_set)) {
        if (events & POLLIN)
          ret++;
        else
          FD_CLR(fd, readfds_fd_set);
      }
      if (writefds_fd_set && FD_ISSET(fd, writefds_fd_set)) {
        if (events & POLLOUT)
          ret++;
        else
          FD_CLR(fd, writefds_fd_set);
      }
      // The read and write sets for this fd are now updated, and our wait has expired, so
      // remove this fd from the set of things we care about.
      ios[fd] = NULL;
      fdio_unsafe_release(io);
    } else if (st == ZX_ERR_TIMED_OUT) {
      break;
    } else {
      fprintf(stderr, "Port wait return unexpected error %d.\n", st);
      errno = EINVAL;
      ret = -1;
      goto cleanup;
    }

    // After pulling the first packet out, poll without blocking by doing another wait with a
    // deadline in the past. This will populate any other members of the read/write set that
    // are ready to go now.
    deadline = 0;
  }

  // If there are any entries left in ios at this point, we have not received a port packet
  // indicating that those fds are readable or writable and so we should clear those from the
  // read/write sets.
  for (int fd = 0; fd < nfds; ++fd) {
    if (ios[fd]) {
      if (readfds_fd_set && FD_ISSET(fd, readfds_fd_set)) {
        FD_CLR(fd, readfds_fd_set);
      }
      if (writefds_fd_set && FD_ISSET(fd, writefds_fd_set)) {
        FD_CLR(fd, writefds_fd_set);
      }
    }
  }

cleanup:
  // Release reference to any fdio objects we acquired with fdio_unsafe_fd_to_io().
  for (int fd = 0; fd < nfds; ++fd) {
    if (ios[fd]) {
      fdio_unsafe_release(ios[fd]);
    }
  }

  if (port != ZX_HANDLE_INVALID) {
    zx_handle_close(port);
  }
  return ret;
}
