#include "cache.h"
#include "compat/terminal.h"
#include "sigchain.h"
#include "strbuf.h"
#include "run-command.h"
#include "string-list.h"
#include "hashmap.h"

#if defined(HAVE_DEV_TTY) || defined(GIT_WINDOWS_NATIVE)

static void restore_term_on_signal(int sig)
{
	restore_term();
	/* restore_term calls sigchain_pop_common */
	raise(sig);
}

#ifdef HAVE_DEV_TTY

#define INPUT_PATH "/dev/tty"
#define OUTPUT_PATH "/dev/tty"

static volatile sig_atomic_t term_fd_needs_closing;
static int term_fd = -1;
static struct termios old_term;

static const char *background_resume_msg;
static const char *restore_error_msg;
static volatile sig_atomic_t ttou_received;

/* async safe error function for use by signal handlers. */
static void write_err(const char *msg)
{
	write_in_full(2, "error: ", strlen("error: "));
	write_in_full(2, msg, strlen(msg));
	write_in_full(2, "\n", 1);
}

static void print_background_resume_msg(int signo)
{
	int saved_errno = errno;
	sigset_t mask;
	struct sigaction old_sa;
	struct sigaction sa = { .sa_handler = SIG_DFL };

	ttou_received = 1;
	write_err(background_resume_msg);
	sigaction(signo, &sa, &old_sa);
	raise(signo);
	sigemptyset(&mask);
	sigaddset(&mask, signo);
	sigprocmask(SIG_UNBLOCK, &mask, NULL);
	/* Stopped here */
	sigprocmask(SIG_BLOCK, &mask, NULL);
	sigaction(signo, &old_sa, NULL);
	errno = saved_errno;
}

static void restore_terminal_on_suspend(int signo)
{
	int saved_errno = errno;
	int res;
	struct termios t;
	sigset_t mask;
	struct sigaction old_sa;
	struct sigaction sa = { .sa_handler = SIG_DFL };
	int can_restore = 1;

	if (tcgetattr(term_fd, &t) < 0)
		can_restore = 0;

	if (tcsetattr(term_fd, TCSAFLUSH, &old_term) < 0)
		write_err(restore_error_msg);

	sigaction(signo, &sa, &old_sa);
	raise(signo);
	sigemptyset(&mask);
	sigaddset(&mask, signo);
	sigprocmask(SIG_UNBLOCK, &mask, NULL);
	/* Stopped here */
	sigprocmask(SIG_BLOCK, &mask, NULL);
	sigaction(signo, &old_sa, NULL);
	if (!can_restore) {
		write_err(restore_error_msg);
		goto out;
	}
	/*
	 * If we resume in the background then we receive SIGTTOU when calling
	 * tcsetattr() below. Set up a handler to print an error message in that
	 * case.
	 */
	sigemptyset(&mask);
	sigaddset(&mask, SIGTTOU);
	sa.sa_mask = old_sa.sa_mask;
	sa.sa_handler = print_background_resume_msg;
	sa.sa_flags = SA_RESTART;
	sigaction(SIGTTOU, &sa, &old_sa);
 again:
	ttou_received = 0;
	sigprocmask(SIG_UNBLOCK, &mask, NULL);
	res = tcsetattr(term_fd, TCSAFLUSH, &t);
	sigprocmask(SIG_BLOCK, &mask, NULL);
	if (ttou_received)
		goto again;
	else if (res < 0)
		write_err(restore_error_msg);
	sigaction(SIGTTOU, &old_sa, NULL);
 out:
	errno = saved_errno;
}

static void reset_job_signals(void)
{
	if (restore_error_msg) {
		signal(SIGTTIN, SIG_DFL);
		signal(SIGTTOU, SIG_DFL);
		signal(SIGTSTP, SIG_DFL);
		restore_error_msg = NULL;
		background_resume_msg = NULL;
	}
}

static void close_term_fd(void)
{
	if (term_fd_needs_closing)
		close(term_fd);
	term_fd_needs_closing = 0;
	term_fd = -1;
}

void restore_term(void)
{
	if (term_fd < 0)
		return;

	tcsetattr(term_fd, TCSAFLUSH, &old_term);
	close_term_fd();
	sigchain_pop_common();
	reset_job_signals();
}

int save_term(enum save_term_flags flags)
{
	struct sigaction sa;

	if (term_fd < 0)
		term_fd = ((flags & SAVE_TERM_STDIN)
			   ? 0
			   : open("/dev/tty", O_RDWR));
	if (term_fd < 0)
		return -1;
	term_fd_needs_closing = !(flags & SAVE_TERM_STDIN);
	if (tcgetattr(term_fd, &old_term) < 0) {
		close_term_fd();
		return -1;
	}
	sigchain_push_common(restore_term_on_signal);
	/*
	 * If job control is disabled then the shell will have set the
	 * disposition of SIGTSTP to SIG_IGN.
	 */
	sigaction(SIGTSTP, NULL, &sa);
	if (sa.sa_handler == SIG_IGN)
		return 0;

	/* avoid calling gettext() from signal handler */
	background_resume_msg = _("cannot resume in the background, please use 'fg' to resume");
	restore_error_msg = _("cannot restore terminal settings");
	sa.sa_handler = restore_terminal_on_suspend;
	sa.sa_flags = SA_RESTART;
	sigemptyset(&sa.sa_mask);
	sigaddset(&sa.sa_mask, SIGTSTP);
	sigaddset(&sa.sa_mask, SIGTTIN);
	sigaddset(&sa.sa_mask, SIGTTOU);
	sigaction(SIGTSTP, &sa, NULL);
	sigaction(SIGTTIN, &sa, NULL);
	sigaction(SIGTTOU, &sa, NULL);

	return 0;
}

static int disable_bits(enum save_term_flags flags, tcflag_t bits)
{
	struct termios t;

	if (save_term(flags) < 0)
		return -1;

	t = old_term;

	t.c_lflag &= ~bits;
	if (bits & ICANON) {
		t.c_cc[VMIN] = 1;
		t.c_cc[VTIME] = 0;
	}
	if (!tcsetattr(term_fd, TCSAFLUSH, &t))
		return 0;

	sigchain_pop_common();
	reset_job_signals();
	close_term_fd();
	return -1;
}

static int disable_echo(enum save_term_flags flags)
{
	return disable_bits(flags, ECHO);
}

static int enable_non_canonical(enum save_term_flags flags)
{
	return disable_bits(flags, ICANON | ECHO);
}

/*
 * On macos it is not possible to use poll() with a terminal so use select
 * instead.
 */
static int getchar_with_timeout(int timeout)
{
	struct timeval tv, *tvp = NULL;
	fd_set readfds;
	int res;

 again:
	if (timeout >= 0) {
		tv.tv_sec = timeout / 1000;
		tv.tv_usec = (timeout % 1000) * 1000;
		tvp = &tv;
	}

	FD_ZERO(&readfds);
	FD_SET(0, &readfds);
	res = select(1, &readfds, NULL, NULL, tvp);
	if (!res)
		return EOF;
	if (res < 0) {
		if (errno == EINTR)
			goto again;
		else
			return EOF;
	}
	return getchar();
}

#elif defined(GIT_WINDOWS_NATIVE)

#define INPUT_PATH "CONIN$"
#define OUTPUT_PATH "CONOUT$"
#define FORCE_TEXT "t"

static int use_stty = 1;
static struct string_list stty_restore = STRING_LIST_INIT_DUP;
static HANDLE hconin = INVALID_HANDLE_VALUE;
static HANDLE hconout = INVALID_HANDLE_VALUE;
static DWORD cmode_in, cmode_out;

void restore_term(void)
{
	if (use_stty) {
		int i;
		struct child_process cp = CHILD_PROCESS_INIT;

		if (stty_restore.nr == 0)
			return;

		strvec_push(&cp.args, "stty");
		for (i = 0; i < stty_restore.nr; i++)
			strvec_push(&cp.args, stty_restore.items[i].string);
		run_command(&cp);
		string_list_clear(&stty_restore, 0);
		return;
	}

	sigchain_pop_common();

	if (hconin == INVALID_HANDLE_VALUE)
		return;

	SetConsoleMode(hconin, cmode_in);
	CloseHandle(hconin);
	if (cmode_out) {
		assert(hconout != INVALID_HANDLE_VALUE);
		SetConsoleMode(hconout, cmode_out);
		CloseHandle(hconout);
	}

	hconin = hconout = INVALID_HANDLE_VALUE;
}

int save_term(enum save_term_flags flags)
{
	hconin = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE,
	    FILE_SHARE_READ, NULL, OPEN_EXISTING,
	    FILE_ATTRIBUTE_NORMAL, NULL);
	if (hconin == INVALID_HANDLE_VALUE)
		return -1;

	if (flags & SAVE_TERM_DUPLEX) {
		hconout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL, NULL);
		if (hconout == INVALID_HANDLE_VALUE)
			goto error;

		GetConsoleMode(hconout, &cmode_out);
	}

	GetConsoleMode(hconin, &cmode_in);
	use_stty = 0;
	sigchain_push_common(restore_term_on_signal);
	return 0;
error:
	CloseHandle(hconin);
	hconin = INVALID_HANDLE_VALUE;
	return -1;
}

static int disable_bits(enum save_term_flags flags, DWORD bits)
{
	if (use_stty) {
		struct child_process cp = CHILD_PROCESS_INIT;

		strvec_push(&cp.args, "stty");

		if (bits & ENABLE_LINE_INPUT) {
			string_list_append(&stty_restore, "icanon");
			/*
			 * POSIX allows VMIN and VTIME to overlap with VEOF and
			 * VEOL - let's hope that is not the case on windows.
			 */
			strvec_pushl(&cp.args, "-icanon", "min", "1", "time", "0", NULL);
		}

		if (bits & ENABLE_ECHO_INPUT) {
			string_list_append(&stty_restore, "echo");
			strvec_push(&cp.args, "-echo");
		}

		if (bits & ENABLE_PROCESSED_INPUT) {
			string_list_append(&stty_restore, "-ignbrk");
			string_list_append(&stty_restore, "intr");
			string_list_append(&stty_restore, "^c");
			strvec_push(&cp.args, "ignbrk");
			strvec_push(&cp.args, "intr");
			strvec_push(&cp.args, "");
		}

		if (run_command(&cp) == 0)
			return 0;

		/* `stty` could not be executed; access the Console directly */
		use_stty = 0;
	}

	if (save_term(flags) < 0)
		return -1;

	if (!SetConsoleMode(hconin, cmode_in & ~bits)) {
		CloseHandle(hconin);
		hconin = INVALID_HANDLE_VALUE;
		sigchain_pop_common();
		return -1;
	}

	return 0;
}

static int disable_echo(enum save_term_flags flags)
{
	return disable_bits(flags, ENABLE_ECHO_INPUT);
}

static int enable_non_canonical(enum save_term_flags flags)
{
	return disable_bits(flags,
			    ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
}

/*
 * Override `getchar()`, as the default implementation does not use
 * `ReadFile()`.
 *
 * This poses a problem when we want to see whether the standard
 * input has more characters, as the default of Git for Windows is to start the
 * Bash in a MinTTY, which uses a named pipe to emulate a pty, in which case
 * our `poll()` emulation calls `PeekNamedPipe()`, which seems to require
 * `ReadFile()` to be called first to work properly (it only reports 0
 * available bytes, otherwise).
 *
 * So let's just override `getchar()` with a version backed by `ReadFile()` and
 * go our merry ways from here.
 */
static int mingw_getchar(void)
{
	DWORD read = 0;
	unsigned char ch;

	if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE), &ch, 1, &read, NULL))
		return EOF;

	if (!read) {
		error("Unexpected 0 read");
		return EOF;
	}

	return ch;
}
#define getchar mingw_getchar

static int getchar_with_timeout(int timeout)
{
	struct pollfd pfd = { .fd = 0, .events = POLLIN };

	if (poll(&pfd, 1, timeout) < 1)
		return EOF;

	return getchar();
}

#endif

#ifndef FORCE_TEXT
#define FORCE_TEXT
#endif

char *git_terminal_prompt(const char *prompt, int echo)
{
	static struct strbuf buf = STRBUF_INIT;
	int r;
	FILE *input_fh, *output_fh;

	input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT);
	if (!input_fh)
		return NULL;

	output_fh = fopen(OUTPUT_PATH, "w" FORCE_TEXT);
	if (!output_fh) {
		fclose(input_fh);
		return NULL;
	}

	if (!echo && disable_echo(0)) {
		fclose(input_fh);
		fclose(output_fh);
		return NULL;
	}

	fputs(prompt, output_fh);
	fflush(output_fh);

	r = strbuf_getline_lf(&buf, input_fh);
	if (!echo) {
		putc('\n', output_fh);
		fflush(output_fh);
	}

	restore_term();
	fclose(input_fh);
	fclose(output_fh);

	if (r == EOF)
		return NULL;
	return buf.buf;
}

/*
 * The `is_known_escape_sequence()` function returns 1 if the passed string
 * corresponds to an Escape sequence that the terminal capabilities contains.
 *
 * To avoid depending on ncurses or other platform-specific libraries, we rely
 * on the presence of the `infocmp` executable to do the job for us (failing
 * silently if the program is not available or refused to run).
 */
struct escape_sequence_entry {
	struct hashmap_entry entry;
	char sequence[FLEX_ARRAY];
};

static int sequence_entry_cmp(const void *hashmap_cmp_fn_data UNUSED,
			      const struct escape_sequence_entry *e1,
			      const struct escape_sequence_entry *e2,
			      const void *keydata)
{
	return strcmp(e1->sequence, keydata ? keydata : e2->sequence);
}

static int is_known_escape_sequence(const char *sequence)
{
	static struct hashmap sequences;
	static int initialized;

	if (!initialized) {
		struct child_process cp = CHILD_PROCESS_INIT;
		struct strbuf buf = STRBUF_INIT;
		char *p, *eol;

		hashmap_init(&sequences, (hashmap_cmp_fn)sequence_entry_cmp,
			     NULL, 0);

		strvec_pushl(&cp.args, "infocmp", "-L", "-1", NULL);
		if (pipe_command(&cp, NULL, 0, &buf, 0, NULL, 0))
			strbuf_setlen(&buf, 0);

		for (eol = p = buf.buf; *p; p = eol + 1) {
			p = strchr(p, '=');
			if (!p)
				break;
			p++;
			eol = strchrnul(p, '\n');

			if (starts_with(p, "\\E")) {
				char *comma = memchr(p, ',', eol - p);
				struct escape_sequence_entry *e;

				p[0] = '^';
				p[1] = '[';
				FLEX_ALLOC_MEM(e, sequence, p, comma - p);
				hashmap_entry_init(&e->entry,
						   strhash(e->sequence));
				hashmap_add(&sequences, &e->entry);
			}
			if (!*eol)
				break;
		}
		initialized = 1;
	}

	return !!hashmap_get_from_hash(&sequences, strhash(sequence), sequence);
}

int read_key_without_echo(struct strbuf *buf)
{
	static int warning_displayed;
	int ch;

	if (warning_displayed || enable_non_canonical(SAVE_TERM_STDIN) < 0) {
		if (!warning_displayed) {
			warning("reading single keystrokes not supported on "
				"this platform; reading line instead");
			warning_displayed = 1;
		}

		return strbuf_getline(buf, stdin);
	}

	strbuf_reset(buf);
	ch = getchar();
	if (ch == EOF) {
		restore_term();
		return EOF;
	}
	strbuf_addch(buf, ch);

	if (ch == '\033' /* ESC */) {
		/*
		 * We are most likely looking at an Escape sequence. Let's try
		 * to read more bytes, waiting at most half a second, assuming
		 * that the sequence is complete if we did not receive any byte
		 * within that time.
		 *
		 * Start by replacing the Escape byte with ^[ */
		strbuf_splice(buf, buf->len - 1, 1, "^[", 2);

		/*
		 * Query the terminal capabilities once about all the Escape
		 * sequences it knows about, so that we can avoid waiting for
		 * half a second when we know that the sequence is complete.
		 */
		while (!is_known_escape_sequence(buf->buf)) {
			ch = getchar_with_timeout(500);
			if (ch == EOF)
				break;
			strbuf_addch(buf, ch);
		}
	}

	restore_term();
	return 0;
}

#else

int save_term(enum save_term_flags flags)
{
	/* no duplex support available */
	return -!!(flags & SAVE_TERM_DUPLEX);
}

void restore_term(void)
{
}

char *git_terminal_prompt(const char *prompt, int echo)
{
	return getpass(prompt);
}

int read_key_without_echo(struct strbuf *buf)
{
	static int warning_displayed;
	const char *res;

	if (!warning_displayed) {
		warning("reading single keystrokes not supported on this "
			"platform; reading line instead");
		warning_displayed = 1;
	}

	res = getpass("");
	strbuf_reset(buf);
	if (!res)
		return EOF;
	strbuf_addstr(buf, res);
	return 0;
}

#endif
