
#include <err.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/un.h>

#include "console-server.h"

enum process_rc {
	PROCESS_OK = 0,
	PROCESS_ERR,
	PROCESS_EXIT,
};

struct console_client {
	int		console_sd;
	int		fd_in;
	int		fd_out;
	bool		is_tty;
	struct termios	orig_termios;
	int		esc_str_pos;
	bool		newline;
};

static const uint8_t esc_str[] = { '~', '.' };

static enum process_rc process_tty(struct console_client *client)
{
	uint8_t e, buf[4096];
	long i;
	ssize_t len;
	int rc;

	len = read(client->fd_in, buf, sizeof(buf));
	if (len < 0)
		return PROCESS_ERR;
	if (len == 0)
		return PROCESS_EXIT;

	/* check escape sequence status */
	for (i = 0; i < len; i++) {
		/* the escape string is only valid after a newline */
		if (buf[i] == '\r') {
			client->newline = true;
			continue;
		}

		if (!client->newline)
			continue;

		e = esc_str[client->esc_str_pos];
		if (buf[i] == e) {
			client->esc_str_pos++;

			/* have we hit the end of the escape string? */
			if (client->esc_str_pos == ARRAY_SIZE(esc_str)) {

				/* flush out any data before the escape */
				if (i > client->esc_str_pos)
					write_buf_to_fd(client->console_sd,
						buf,
						i - client->esc_str_pos);

				return PROCESS_EXIT;
			}
		} else {
			/* if we're partially the way through the escape
			 * string, flush out the bytes we'd skipped */
			if (client->esc_str_pos)
				write_buf_to_fd(client->console_sd,
						esc_str, client->esc_str_pos);
			client->esc_str_pos = 0;
			client->newline = false;
		}
	}

	rc = write_buf_to_fd(client->console_sd, buf,
			len - client->esc_str_pos);
	if (rc < 0)
		return PROCESS_ERR;

	return PROCESS_OK;
}


static int process_console(struct console_client *client)
{
	uint8_t buf[4096];
	int len, rc;

	len = read(client->console_sd, buf, sizeof(buf));
	if (len < 0) {
		warn("Can't read from server");
		return PROCESS_ERR;
	}
	if (len == 0) {
		fprintf(stderr, "Connection closed\n");
		return PROCESS_EXIT;
	}

	rc = write_buf_to_fd(client->fd_out, buf, len);
	return rc ? PROCESS_ERR : PROCESS_OK;
}

/*
 * Setup our local file descriptors for IO: use stdin/stdout, and if we're on a
 * TTY, put it in canonical mode
 */
static int client_tty_init(struct console_client *client)
{
	struct termios termios;
	int rc;

	client->fd_in = STDIN_FILENO;
	client->fd_out = STDOUT_FILENO;
	client->is_tty = isatty(client->fd_in);

	if (!client->is_tty)
		return 0;

	rc = tcgetattr(client->fd_in, &termios);
	if (rc) {
		warn("Can't get terminal attributes for console");
		return -1;
	}
	memcpy(&client->orig_termios, &termios, sizeof(client->orig_termios));
	cfmakeraw(&termios);

	rc = tcsetattr(client->fd_in, TCSANOW, &termios);
	if (rc) {
		warn("Can't set terminal attributes for console");
		return -1;
	}

	return 0;
}

static int client_init(struct console_client *client)
{
	struct sockaddr_un addr;
	int rc;

	client->console_sd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (!client->console_sd) {
		warn("Can't open socket");
		return -1;
	}

	memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	memcpy(addr.sun_path, console_socket_path, console_socket_path_len);

	rc = connect(client->console_sd, (struct sockaddr *)&addr,
			sizeof(addr));
	if (rc) {
		warn("Can't connect to console server");
		close(client->console_sd);
		return -1;
	}

	return 0;
}

static void client_fini(struct console_client *client)
{
	if (client->is_tty)
		tcsetattr(client->fd_in, TCSANOW, &client->orig_termios);
	close(client->console_sd);
}

int main(void)
{
	struct console_client _client, *client;
	struct pollfd pollfds[2];
	enum process_rc prc;
	int rc;

	client = &_client;
	memset(client, 0, sizeof(*client));

	rc = client_init(client);
	if (rc)
		return EXIT_FAILURE;

	rc = client_tty_init(client);
	if (rc)
		goto out_fini;

	for (;;) {
		pollfds[0].fd = client->fd_in;
		pollfds[0].events = POLLIN;
		pollfds[1].fd = client->console_sd;
		pollfds[1].events = POLLIN;

		rc = poll(pollfds, 2, -1);
		if (rc < 0) {
			warn("Poll failure");
			break;
		}

		if (pollfds[0].revents)
			prc = process_tty(client);

		if (prc == PROCESS_OK && pollfds[1].revents)
			prc = process_console(client);

		rc = (prc == PROCESS_ERR) ? -1 : 0;
		if (prc != PROCESS_OK)
			break;
	}

out_fini:
	client_fini(client);
	return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}

