/* Copyright 2019 The Chromium OS 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 <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include "2common.h"
#include "subprocess.h"

#define MAX_CB_BUF_SIZE 2048

static int init_target_private(struct subprocess_target *target)
{
	switch (target->type) {
	case TARGET_BUFFER:
	case TARGET_BUFFER_NULL_TERMINATED:
	case TARGET_CALLBACK:
		return pipe(target->priv.pipefd);
	default:
		return 0;
	}
}

static int flags_for_fd(int fd)
{
	switch (fd) {
	case STDIN_FILENO:
		return O_RDONLY;
	case STDOUT_FILENO:
	case STDERR_FILENO:
		return O_WRONLY;
	default:
		return -1;
	}
}

static int connect_process_target(struct subprocess_target *target, int fd)
{
	int target_fd;

	switch (target->type) {
	case TARGET_NULL:
		target_fd = open("/dev/null", flags_for_fd(fd));
		break;
	case TARGET_FD:
		target_fd = target->fd;
		break;
	case TARGET_FILE:
		target_fd = fileno(target->file);
		break;
	case TARGET_BUFFER:
	case TARGET_BUFFER_NULL_TERMINATED:
	case TARGET_CALLBACK:
		switch (fd) {
		case STDIN_FILENO:
			target_fd = target->priv.pipefd[0];
			close(target->priv.pipefd[1]);
			break;
		case STDOUT_FILENO:
		case STDERR_FILENO:
			target_fd = target->priv.pipefd[1];
			close(target->priv.pipefd[0]);
			break;
		default:
			return -1;
		}
		break;
	default:
		return -1;
	}

	return dup2(target_fd, fd);
}

static int process_target_input_buffer(struct subprocess_target *target)
{
	ssize_t write_rv;
	size_t bytes_to_write;
	char *buf;

	switch (target->type) {
	case TARGET_BUFFER:
		bytes_to_write = target->buffer.size;
		break;
	case TARGET_BUFFER_NULL_TERMINATED:
		bytes_to_write = strlen(target->buffer.buf);
		break;
	default:
		return -1;
	}

	buf = target->buffer.buf;
	while (bytes_to_write) {
		write_rv = write(target->priv.pipefd[1], buf, bytes_to_write);
		if (write_rv <= 0)
			return -1;
		buf += write_rv;
		bytes_to_write -= write_rv;
	}

	return 0;
}

static int process_target_input_cb(struct subprocess_target *target)
{
	ssize_t write_rv, bytes_to_write;
	char buf[MAX_CB_BUF_SIZE];
	char *bufptr;

	for (;;) {
		bytes_to_write = target->callback.cb(buf, MAX_CB_BUF_SIZE,
						     target->callback.data);
		if (bytes_to_write < 0 || bytes_to_write > MAX_CB_BUF_SIZE)
			return -1;
		if (bytes_to_write == 0)
			return 0;

		bufptr = buf;
		while (bytes_to_write) {
			write_rv = write(target->priv.pipefd[1], bufptr,
					 bytes_to_write);
			if (write_rv <= 0)
				return -1;
			bufptr += write_rv;
			bytes_to_write -= write_rv;
		}
	}
}

static int process_target_input(struct subprocess_target *target)
{
	int rv;

	switch (target->type) {
	case TARGET_BUFFER:
	case TARGET_BUFFER_NULL_TERMINATED:
	case TARGET_CALLBACK:
		break;
	default:
		return 0;
	}

	close(target->priv.pipefd[0]);
	switch (target->type) {
	case TARGET_BUFFER:
	case TARGET_BUFFER_NULL_TERMINATED:
		rv = process_target_input_buffer(target);
		break;
	case TARGET_CALLBACK:
		rv = process_target_input_cb(target);
		break;
	default:
		return -1;
	}

	close(target->priv.pipefd[1]);
	return rv;
}

static int process_target_output_buffer(struct subprocess_target *target)
{
	ssize_t read_rv;
	size_t bytes_remaining;

	switch (target->type) {
	case TARGET_BUFFER:
		bytes_remaining = target->buffer.size;
		break;
	case TARGET_BUFFER_NULL_TERMINATED:
		if (target->buffer.size == 0)
			return -1;
		bytes_remaining = target->buffer.size - 1;
		break;
	default:
		return 0;
	}

	target->buffer.bytes_consumed = 0;
	while (bytes_remaining) {
		read_rv = read(
			target->priv.pipefd[0],
			target->buffer.buf + target->buffer.bytes_consumed,
			bytes_remaining);
		if (read_rv < 0)
			return -1;
		if (read_rv == 0)
			break;
		target->buffer.bytes_consumed += read_rv;
		bytes_remaining -= read_rv;
	}

	if (target->type == TARGET_BUFFER_NULL_TERMINATED)
		target->buffer.buf[target->buffer.bytes_consumed] = '\0';
	return 0;
}

static int process_target_output_cb(struct subprocess_target *target)
{
	char buf[MAX_CB_BUF_SIZE];
	ssize_t rv;

	for (;;) {
		rv = read(target->priv.pipefd[0], buf, MAX_CB_BUF_SIZE);
		if (rv < 0)
			return -1;
		if (rv == 0)
			break;
		if (target->callback.cb(buf, rv, target->callback.data) < 0)
			return -1;
	}

	return 0;
}

static int process_target_output(struct subprocess_target *target)
{
	int rv;

	switch (target->type) {
	case TARGET_BUFFER:
	case TARGET_BUFFER_NULL_TERMINATED:
	case TARGET_CALLBACK:
		break;
	default:
		return 0;
	}

	close(target->priv.pipefd[1]);
	switch (target->type) {
	case TARGET_BUFFER:
	case TARGET_BUFFER_NULL_TERMINATED:
		rv = process_target_output_buffer(target);
		break;
	case TARGET_CALLBACK:
		rv = process_target_output_cb(target);
		break;
	default:
		return -1;
	}

	close(target->priv.pipefd[0]);
	return rv;
}

static bool contains_spaces(const char *s)
{
	for (size_t i = 0; s[i]; i++) {
		if (isspace(s[i]))
			return true;
	}
	return false;
}

static void subprocess_log_call(const char *const argv[])
{
	VB2_DEBUG("Run:");

	for (size_t i = 0; argv[i]; i++) {
		if (contains_spaces(argv[i]))
			VB2_DEBUG_RAW(" '%s'", argv[i]);
		else
			VB2_DEBUG_RAW(" %s", argv[i]);
	}
	VB2_DEBUG_RAW("\n");
}

struct subprocess_target subprocess_null = {
	.type = TARGET_NULL,
};

struct subprocess_target subprocess_stdin = {
	.type = TARGET_FD,
	.fd = STDIN_FILENO,
};

struct subprocess_target subprocess_stdout = {
	.type = TARGET_FD,
	.fd = STDOUT_FILENO,
};

struct subprocess_target subprocess_stderr = {
	.type = TARGET_FD,
	.fd = STDERR_FILENO,
};

int subprocess_run(const char *const argv[],
		   struct subprocess_target *input,
		   struct subprocess_target *output,
		   struct subprocess_target *error)
{
	int status;
	pid_t pid = -1;

	subprocess_log_call(argv);

	if (!input)
		input = &subprocess_stdin;
	if (!output)
		output = &subprocess_stdout;
	if (!error)
		error = &subprocess_stderr;

	if (init_target_private(input) < 0)
		goto fail;
	if (init_target_private(output) < 0)
		goto fail;
	if (init_target_private(error) < 0)
		goto fail;

	if ((pid = fork()) < 0)
		goto fail;
	if (pid == 0) {
		/* Child process */
		if (connect_process_target(input, STDIN_FILENO) < 0)
			goto fail;
		if (connect_process_target(output, STDOUT_FILENO) < 0)
			goto fail;
		if (connect_process_target(error, STDERR_FILENO) < 0)
			goto fail;
		execvp(*argv, (char *const *)argv);
		goto fail;
	}

	/* Parent process */
	if (process_target_input(input) < 0)
		goto fail;
	if (process_target_output(output) < 0)
		goto fail;
	if (process_target_output(error) < 0)
		goto fail;

	if (waitpid(pid, &status, 0) < 0)
		goto fail;

	if (WIFEXITED(status))
		return WEXITSTATUS(status);

 fail:
	VB2_DEBUG("Failed to execute external command: %s\n", strerror(errno));
	if (pid == 0)
		exit(127);
	return -1;
}
