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

#include <fuchsia/hardware/pty/c/fidl.h>
#include <lib/async-loop/loop.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/io.h>
#include <lib/fdio/spawn.h>
#include <lib/fdio/unsafe.h>
#include <loader-service/loader-service.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

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

static async_loop_t* loop;
static thrd_t loop_thread;

void fuchsia_init_async(void) {
	zx_status_t status;
	status = async_loop_create(&kAsyncLoopConfigNoAttachToThread, &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);
	}
}

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

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 = "/boot/bin/sh",
};

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;
	zx_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) {
	pthread_detach(pthread_self());

	Child* child = voidp;

	zx_signals_t observed;
	zx_object_wait_one(child->handle, ZX_PROCESS_TERMINATED, ZX_TIME_INFINITE, &observed);

	zx_info_process_t info;
	size_t actual;
	zx_object_get_info(child->handle, ZX_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);
	}

	zx_handle_close(child->handle);
	child->handle = ZX_HANDLE_INVALID;

	return NULL;
}

// 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) {
	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;

	// TODO(CF-578): replace most of this with a "shell runner" instead
	zx_status_t status;
	loader_service_t *ldsvc;
	if ((status = loader_service_create_fs(get_async(), &ldsvc)) != ZX_OK) {
		fprintf(stderr, "failed to create loader service: %s\n", zx_status_get_string(status));
		exit(1);
	}

	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));
		loader_service_release(ldsvc);
		exit(1);
	}
	loader_service_release(ldsvc);

	fdio_spawn_action_t actions[4] = {
		{
				.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
				.h = {.id = PA_LDSVC_LOADER, .handle = ldsvc_hnd},
		},
		{
				.action = (in == out) ? FDIO_SPAWN_ACTION_CLONE_FD
															: FDIO_SPAWN_ACTION_TRANSFER_FD,
				.fd = {.local_fd = in, .target_fd = STDIN_FILENO},
		},
		{
				.action = (out == err) ? FDIO_SPAWN_ACTION_CLONE_FD
																: FDIO_SPAWN_ACTION_TRANSFER_FD,
				.fd = {.local_fd = out, .target_fd = STDOUT_FILENO},
		},
		{
				.action = FDIO_SPAWN_ACTION_TRANSFER_FD,
				.fd = {.local_fd = err, .target_fd = STDERR_FILENO},
		},
	};

	zx_handle_t proc = 0;
	char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];

	uint32_t flags = FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_NAMESPACE;
	status = fdio_spawn_etc(ZX_HANDLE_INVALID, flags, argv[0], argv, (const char* const *)env, 4, actions, &proc, err_msg);
	// env is constructed in session.c by child_set_env that always printf's new values and callocs the list pointer.
	// walk each member, freeing them, then free the list.
	char **envf = env;
	while(*envf != NULL) {
		free(*envf++);
	}
	free(env);

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

	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));
		exit(1);
	}

	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) {
		// 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, struct timeval *timeout) {
	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;
}

int fuchsia_open_pty_client(int fd, uint32_t id) {
  fdio_t* io = fdio_unsafe_fd_to_io(fd);
  if (io == NULL) {
    fprintf(stderr, "Failed to open PTY client: couldn't create fdio\n");
    return -1;
  }

  zx_handle_t device_channel, client_channel;
  zx_status_t status =
      zx_channel_create(0 /* flags */, &device_channel, &client_channel);
  if (status != ZX_OK) {
    fprintf(stderr, "Failed to open PTY client: %s\n",
            zx_status_get_string(status));
    return -1;
  }

  zx_status_t fidl_status = fuchsia_hardware_pty_DeviceOpenClient(
      fdio_unsafe_borrow_channel(io), id, device_channel, &status);
  fdio_unsafe_release(io);
  if (fidl_status != ZX_OK) {
    fprintf(stderr, "Failed to open PTY client: %s\n",
            zx_status_get_string(fidl_status));
    zx_handle_close(device_channel);
    zx_handle_close(client_channel);
    return -1;
  }
  if (status != ZX_OK) {
    fprintf(stderr, "Failed to open PTY client: %s\n",
            zx_status_get_string(status));
    zx_handle_close(device_channel);
    zx_handle_close(client_channel);
    return -1;
  }

  int client_fd;
  status = fdio_fd_create(client_channel, &client_fd);
  if (status != ZX_OK) {
    fprintf(stderr, "Failed to open PTY client: %s\n",
            zx_status_get_string(status));
    zx_handle_close(device_channel);
    zx_handle_close(client_channel);
    return -1;
  }
  return client_fd;
}
