// 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 <threads.h>

#include <fuchsia/hardware/pty/c/fidl.h>
#include <lib/async-loop/default.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 <lib/zircon-internal/paths.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"
#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);
	}

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

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 mysig_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, but we'd otherwise be consuming these fd's "some time
  * later" in the child thread. We need to consume them now, so we just
  * decompose them into their handles now. Sadly this repeats some of the work
  * that fdio_spawn would otherwise be doing for us.
  */
	zx_status_t status;
	if (in == out) {
		if ((status = fdio_fd_clone(in, &lr->in)) != ZX_OK) {
			fprintf(stderr, "failed to clone fd %d\n", in);
		}
	} else {
		if ((status = fdio_fd_transfer(in, &lr->in)) != ZX_OK) {
			fprintf(stderr, "failed to transfer fd %d\n", in);
		}
	}
	if (out == err) {
		if ((status = fdio_fd_clone(out, &lr->out)) != ZX_OK) {
			fprintf(stderr, "failed to clone fd %d\n", out);
		}
	} else {
		if ((status = fdio_fd_transfer(out, &lr->out)) != ZX_OK) {
			fprintf(stderr, "failed to transfer fd %d\n", out);
		}
	}
	if ((status = fdio_fd_transfer(err, &lr->err)) != ZX_OK) {
		fprintf(stderr, "failed to transfer 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;
	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;

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

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