#include "git-compat-util.h"
#include "compat/terminal.h"
#include "gettext.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) {
		struct child_process cp = CHILD_PROCESS_INIT;

		if (stty_restore.nr == 0)
			return;

		strvec_push(&cp.args, "stty");
		for (size_t 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 hashmap_entry *he1,
			      const struct hashmap_entry *he2,
			      const void *keydata)
{
	const struct escape_sequence_entry
		*e1 = container_of(he1, const struct escape_sequence_entry, entry),
		*e2 = container_of(he2, const struct escape_sequence_entry, entry);
	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, 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 UNUSED)
{
	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
