/*
 * Based on linux-perf/git scm
 *
 * Some modifications and simplifications for util-linux
 * by Davidlohr Bueso <dave@xxxxxxx> - March 2012.
 */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>

#include "c.h"
#include "xalloc.h"
#include "nls.h"
#include "ttyutils.h"
#include "pager.h"

#define NULL_DEVICE	"/dev/null"

static const char *pager_argv[] = { "sh", "-c", NULL, NULL };

struct child_process {
	const char **argv;
	pid_t pid;
	int in;
	int out;
	int err;

	int org_err;
	int org_out;
	struct sigaction orig_sigint;
	struct sigaction orig_sighup;
	struct sigaction orig_sigterm;
	struct sigaction orig_sigquit;
	struct sigaction orig_sigpipe;

	unsigned no_stdin:1;
	void (*preexec_cb)(void);
};
static struct child_process pager_process;

static inline void close_pair(int fd[2])
{
	close(fd[0]);
	close(fd[1]);
}

static int start_command(struct child_process *cmd)
{
	int need_in;
	int fdin[2];

	/*
	 * In case of errors we must keep the promise to close FDs
	 * that have been passed in via ->in and ->out.
	 */
	need_in = !cmd->no_stdin && cmd->in < 0;
	if (need_in) {
		if (pipe(fdin) < 0) {
			if (cmd->out > 0)
				close(cmd->out);
			return -1;
		}
		cmd->in = fdin[1];
	}

	fflush(NULL);
	cmd->pid = fork();
	if (!cmd->pid) {
		if (need_in) {
			dup2(fdin[0], STDIN_FILENO);
			close_pair(fdin);
		} else if (cmd->in > 0) {
			dup2(cmd->in, STDIN_FILENO);
			close(cmd->in);
		}

		cmd->preexec_cb();
		execvp(cmd->argv[0], (char *const*) cmd->argv);
		errexec(cmd->argv[0]);
	}

	if (cmd->pid < 0) {
		if (need_in)
			close_pair(fdin);
		else if (cmd->in)
			close(cmd->in);
		return -1;
	}

	if (need_in)
		close(fdin[0]);
	else if (cmd->in)
		close(cmd->in);
	return 0;
}

static int wait_or_whine(pid_t pid)
{
	for (;;) {
		int status, code;
		pid_t waiting = waitpid(pid, &status, 0);

		if (waiting < 0) {
			if (errno == EINTR)
				continue;
			err(EXIT_FAILURE, _("waitpid failed (%s)"), strerror(errno));
		}
		if (waiting != pid)
			return -1;
		if (WIFSIGNALED(status))
			return -1;

		if (!WIFEXITED(status))
			return -1;
		code = WEXITSTATUS(status);
		switch (code) {
		case 127:
			return -1;
		case 0:
			return 0;
		default:
			return -1;
		}
	}
}

static int finish_command(struct child_process *cmd)
{
	return wait_or_whine(cmd->pid);
}

static void pager_preexec(void)
{
	/*
	 * Work around bug in "less" by not starting it until we
	 * have real input
	 */
	fd_set in, ex;

	FD_ZERO(&in);
	FD_SET(STDIN_FILENO, &in);
	ex = in;

	select(STDIN_FILENO + 1, &in, NULL, &ex, NULL);

	if (setenv("LESS", "FRSX", 0) != 0)
		warn(_("failed to set the %s environment variable"), "LESS");
}

static void wait_for_pager(void)
{
	if (pager_process.pid == 0)
		return;

	fflush(stdout);
	fflush(stderr);
	/* signal EOF to pager */
	close(STDOUT_FILENO);
	close(STDERR_FILENO);
	finish_command(&pager_process);
}

static void wait_for_pager_signal(int signo)
{
	wait_for_pager();
	raise(signo);
}

static int has_command(const char *cmd)
{
	const char *path;
	char *p, *s;
	int rc = 0;

	if (!cmd)
		goto done;
	if (*cmd == '/') {
		rc = access(cmd, X_OK) == 0;
		goto done;
	}

	path = getenv("PATH");
	if (!path)
		goto done;
	p = xstrdup(path);
	if (!p)
		goto done;

	for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) {
		int fd = open(s, O_RDONLY|O_CLOEXEC);
		if (fd < 0)
			continue;
		rc = faccessat(fd, cmd, X_OK, 0) == 0;
		close(fd);
		if (rc)
			break;
	}
	free(p);
done:
	/*fprintf(stderr, "has PAGER %s rc=%d\n", cmd, rc);*/
	return rc;
}

static void __setup_pager(void)
{
	const char *pager = getenv("PAGER");
	struct sigaction sa;

	if (!isatty(STDOUT_FILENO))
		return;

	if (!pager)
		pager = "less";
	else if (!*pager || !strcmp(pager, "cat"))
		return;

	if (!has_command(pager))
		return;

	/* spawn the pager */
	pager_argv[2] = pager;
	pager_process.argv = pager_argv;
	pager_process.in = -1;
	pager_process.preexec_cb = pager_preexec;

	if (start_command(&pager_process))
		return;

	/* original process continues, but writes to the pipe */
	dup2(pager_process.in, STDOUT_FILENO);
	if (isatty(STDERR_FILENO))
		dup2(pager_process.in, STDERR_FILENO);
	close(pager_process.in);

	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = wait_for_pager_signal;

	/* this makes sure that the parent terminates after the pager */
	sigaction(SIGINT,  &sa, &pager_process.orig_sigint);
	sigaction(SIGHUP,  &sa, &pager_process.orig_sighup);
	sigaction(SIGTERM, &sa, &pager_process.orig_sigterm);
	sigaction(SIGQUIT, &sa, &pager_process.orig_sigquit);
	sigaction(SIGPIPE, &sa, &pager_process.orig_sigpipe);
}

/* Setup pager and redirects output to the $PAGER. The pager is closed at exit.
 */
void pager_redirect(void)
{
	if (pager_process.pid)
		return;		/* already running */

	__setup_pager();

	atexit(wait_for_pager);
}

/* Setup pager and redirect output, the pager may be closed by pager_close().
 */
void pager_open(void)
{
	if (pager_process.pid)
		return;		/* already running */

	pager_process.org_out = dup(STDOUT_FILENO);
	pager_process.org_err = dup(STDERR_FILENO);

	__setup_pager();
}

/* Close pager and restore original std{out,err}.
 */
void pager_close(void)
{
	if (pager_process.pid == 0)
		return;

	wait_for_pager();

	/* restore original output */
	dup2(pager_process.org_out, STDOUT_FILENO);
	dup2(pager_process.org_err, STDERR_FILENO);

	close(pager_process.org_out);
	close(pager_process.org_err);

	/* restore original segnals setting */
	sigaction(SIGINT,  &pager_process.orig_sigint, NULL);
	sigaction(SIGHUP,  &pager_process.orig_sighup, NULL);
	sigaction(SIGTERM, &pager_process.orig_sigterm, NULL);
	sigaction(SIGQUIT, &pager_process.orig_sigquit, NULL);
	sigaction(SIGPIPE, &pager_process.orig_sigpipe, NULL);

	memset(&pager_process, 0, sizeof(pager_process));
}

#ifdef TEST_PROGRAM_PAGER

#define MAX 255

int main(int argc __attribute__ ((__unused__)),
	 char *argv[] __attribute__ ((__unused__)))
{
	int i;

	pager_redirect();
	for (i = 0; i < MAX; i++)
		printf("%d\n", i);
	return EXIT_SUCCESS;
}
#endif /* TEST_PROGRAM_PAGER */
