// 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 <launchpad/launchpad.h>
#include <magenta/syscalls.h>
#include <pthread.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "openbsd-compat/bsd-misc.h"

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;
}

struct passwd *getpwent(void) {
  static struct passwd static_passwd = {
      .pw_name = "fuchsia",
      .pw_passwd = "",
      .pw_uid = 23,  // matches MX_UID
      .pw_gid = 23,
      .pw_gecos = "Fuchsia",
      .pw_dir = "/",
      .pw_shell = "/boot/bin/sh",
  };

  return &static_passwd;
}

struct passwd *getpwnam(const char *name) {
  return getpwent();
}

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

#define ARGV_MAX 256

typedef struct {
  enum {
    UNUSED, RUNNING, STOPPED
  } state;
  mx_handle_t handle;
  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 mysig_t sigchld_handler = SIG_IGN;

static void* wait_thread_func(void* voidp) {
  Child* child = voidp;

  mx_signals_t observed;
  mx_object_wait_one(child->handle, MX_PROCESS_SIGNALED, MX_TIME_INFINITE, &observed);

  mx_info_process_t info;
  size_t actual;
  mx_object_get_info(child->handle, MX_INFO_PROCESS, &info, sizeof(info), &actual, NULL);

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

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

  return NULL;
}

pid_t fuchsia_launch_child(const char *command, int in, int out, int err) {
  const char *argv[ARGV_MAX];
  int argc = 1;
  argv[0] = "/boot/bin/sh";
  if (command) {
    argv[argc++] = "-c";
    argv[argc++] = command;
  } else {
    command = argv[0];
  }
  argv[argc] = NULL;

  launchpad_t *lp;
  launchpad_create(0, command, &lp);
  launchpad_load_from_file(lp, argv[0]);
  launchpad_set_args(lp, argc, argv);
  launchpad_clone(lp, LP_CLONE_MXIO_ROOT|LP_CLONE_MXIO_CWD);
  // TODO: set up environment
  launchpad_transfer_fd(lp, in, STDIN_FILENO);
  launchpad_transfer_fd(lp, out, STDOUT_FILENO);
  launchpad_transfer_fd(lp, err, STDERR_FILENO);

  mx_handle_t proc = 0;
  const char* errmsg;

  mx_status_t status = launchpad_go(lp, &proc, &errmsg);
  if (status < 0) {
    fprintf(stderr, "error from launchpad_go: %s\n", errmsg);
    exit(1);
  }

  pid_t pid = get_unused_pid();
  Child* child = get_child(pid);
  child->state = RUNNING;
  child->handle = proc;

  pthread_t wait_thread;
  if (pthread_create(&wait_thread, NULL, wait_thread_func, (void*)child) != 0) {
    fprintf(stderr, "Failed to create process waiter thread: %s\n", strerror(errno));
  }

  return pid;
}

mysig_t mysignal(int signum, mysig_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) {
    *status = child->exit_code;
  }
  child->state = UNUSED;

  return pid;
}
