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

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;

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