/**
 * Copyright © 2016 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <err.h>
#include <errno.h>
#include <getopt.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"
#include "config.h"

#define EXIT_ESCAPE 2

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

enum esc_type {
	ESC_TYPE_SSH,
	ESC_TYPE_STR,
};

struct ssh_esc_state {
	uint8_t state;
};

struct str_esc_state {
	const uint8_t *str;
	size_t pos;
};

struct console_client {
	int console_sd;
	int fd_in;
	int fd_out;
	bool is_tty;
	struct termios orig_termios;
	enum esc_type esc_type;
	union {
		struct ssh_esc_state ssh;
		struct str_esc_state str;
	} esc_state;
};

static enum process_rc process_ssh_tty(struct console_client *client,
				       const uint8_t *buf, size_t len)
{
	struct ssh_esc_state *esc_state = &client->esc_state.ssh;
	const uint8_t *out_buf = buf;
	int rc;

	for (size_t i = 0; i < len; ++i) {
		switch (buf[i]) {
		case '.':
			if (esc_state->state != '~') {
				esc_state->state = '\0';
				break;
			}
			return PROCESS_ESC;
		case '~':
			if (esc_state->state != '\r') {
				esc_state->state = '\0';
				break;
			}
			esc_state->state = '~';
			/* We need to print everything to skip the tilde */
			rc = write_buf_to_fd(client->console_sd, out_buf,
					     i - (out_buf - buf));
			if (rc < 0) {
				return PROCESS_ERR;
			}
			out_buf = &buf[i + 1];
			break;
		case '\r':
			esc_state->state = '\r';
			break;
		default:
			esc_state->state = '\0';
		}
	}

	rc = write_buf_to_fd(client->console_sd, out_buf,
			     len - (out_buf - buf));
	return rc < 0 ? PROCESS_ERR : PROCESS_OK;
}

static enum process_rc process_str_tty(struct console_client *client,
				       const uint8_t *buf, size_t len)
{
	struct str_esc_state *esc_state = &client->esc_state.str;
	enum process_rc prc = PROCESS_OK;
	size_t i;

	for (i = 0; i < len; ++i) {
		if (buf[i] == esc_state->str[esc_state->pos]) {
			esc_state->pos++;
		} else {
			esc_state->pos = 0;
		}

		if (esc_state->str[esc_state->pos] == '\0') {
			prc = PROCESS_ESC;
			++i;
			break;
		}
	}

	if (write_buf_to_fd(client->console_sd, buf, i) < 0) {
		return PROCESS_ERR;
	}
	return prc;
}

static enum process_rc process_tty(struct console_client *client)
{
	uint8_t buf[4096];
	ssize_t len;

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

	switch (client->esc_type) {
	case ESC_TYPE_SSH:
		return process_ssh_tty(client, buf, len);
	case ESC_TYPE_STR:
		return process_str_tty(client, buf, len);
	default:
		return PROCESS_ERR;
	}
}

static int process_console(struct console_client *client)
{
	uint8_t buf[4096];
	ssize_t len;
	int 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 config *config,
		       const char *console_id)
{
	const char *resolved_id = NULL;
	struct sockaddr_un addr;
	socket_path_t path;
	ssize_t len;
	int rc;

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

	/* Get the console id */
	resolved_id = config_resolve_console_id(config, console_id);

	memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	len = console_socket_path(addr.sun_path, resolved_id);
	if (len < 0) {
		if (errno) {
			warn("Failed to configure socket: %s", strerror(errno));
		} else {
			warn("Socket name length exceeds buffer limits");
		}
		goto cleanup;
	}

	rc = connect(client->console_sd, (struct sockaddr *)&addr,
		     sizeof(addr) - sizeof(addr.sun_path) + len);
	if (!rc) {
		return 0;
	}

	console_socket_path_readable(&addr, len, path);
	warn("Can't connect to console server '@%s'", path);
cleanup:
	close(client->console_sd);
	return -1;
}

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(int argc, char *argv[])
{
	struct console_client _client;
	struct console_client *client;
	struct pollfd pollfds[2];
	enum process_rc prc = PROCESS_OK;
	const char *config_path = NULL;
	struct config *config = NULL;
	const char *console_id = NULL;
	const uint8_t *esc = NULL;
	int rc;

	client = &_client;
	memset(client, 0, sizeof(*client));
	client->esc_type = ESC_TYPE_SSH;

	for (;;) {
		rc = getopt(argc, argv, "c:e:i:");
		if (rc == -1) {
			break;
		}

		switch (rc) {
		case 'c':
			if (optarg[0] == '\0') {
				fprintf(stderr, "Config str cannot be empty\n");
				return EXIT_FAILURE;
			}
			config_path = optarg;
			break;
		case 'e':
			if (optarg[0] == '\0') {
				fprintf(stderr, "Escape str cannot be empty\n");
				return EXIT_FAILURE;
			}
			esc = (const uint8_t *)optarg;
			break;
		case 'i':
			if (optarg[0] == '\0') {
				fprintf(stderr,
					"Socket ID str cannot be empty\n");
				return EXIT_FAILURE;
			}
			console_id = optarg;
			break;
		default:
			fprintf(stderr,
				"Usage: %s "
				"[-e <escape sequence>]"
				"[-i <console ID>]"
				"[-c <config>]\n",
				argv[0]);
			return EXIT_FAILURE;
		}
	}

	if (config_path) {
		config = config_init(config_path);
		if (!config) {
			warnx("Can't read configuration, exiting.");
			return EXIT_FAILURE;
		}

		if (!esc) {
			esc = (const uint8_t *)config_get_value(
				config, "escape-sequence");
		}
	}

	if (esc) {
		client->esc_type = ESC_TYPE_STR;
		client->esc_state.str.str = esc;
	}

	rc = client_init(client, config, console_id);
	if (rc) {
		goto out_config_fini;
	}

	rc = client_tty_init(client);
	if (rc) {
		goto out_client_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_client_fini:
	client_fini(client);

out_config_fini:
	if (config_path) {
		config_fini(config);
	}

	if (prc == PROCESS_ESC) {
		return EXIT_ESCAPE;
	}
	return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
