/**
 * 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 <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>

#include "console-server.h"
#include "config.h"

struct tty_handler {
	struct handler handler;
	struct console *console;
	struct ringbuffer_consumer *rbc;
	struct poller *poller;
	int fd;
	int fd_flags;
	bool blocked;
};

static struct tty_handler *to_tty_handler(struct handler *handler)
{
	return container_of(handler, struct tty_handler, handler);
}

static void tty_set_fd_blocking(struct tty_handler *th, bool fd_blocking)
{
	int flags;

	flags = th->fd_flags & ~O_NONBLOCK;
	if (!fd_blocking) {
		flags |= O_NONBLOCK;
	}

	if (flags != th->fd_flags) {
		fcntl(th->fd, F_SETFL, flags);
		th->fd_flags = flags;
	}
}

/*
 * A "blocked" handler indicates that the last write returned EAGAIN
 * (==EWOULDBLOCK), so we know not to continue writing (for non-forced output),
 * as it'll just return EAGAIN again.
 *
 * Once we detect this, we watch for POLLOUT in the poller events. A
 * POLLOUT indicates that the fd is no longer blocking, so we clear
 * blocked mode and can continue writing.
 */
static void tty_set_blocked(struct tty_handler *th, bool blocked)
{
	int events;

	if (blocked == th->blocked) {
		return;
	}

	th->blocked = blocked;
	events = POLLIN;

	if (th->blocked) {
		events |= POLLOUT;
	}

	console_poller_set_events(th->console, th->poller, events);
}

static int tty_drain_queue(struct tty_handler *th, size_t force_len)
{
	size_t len;
	size_t total_len;
	ssize_t wlen;
	uint8_t *buf;

	/* if we're forcing data, we need to clear non-blocking mode */
	if (force_len) {
		tty_set_fd_blocking(th, true);

		/* no point writing, we'll just see -EAGAIN */
	} else if (th->blocked) {
		return 0;
	}

	total_len = 0;

	for (;;) {
		len = ringbuffer_dequeue_peek(th->rbc, total_len, &buf);
		if (!len) {
			break;
		}

		/* write as little as possible while blocking */
		if (force_len && force_len < total_len + len) {
			len = force_len - total_len;
		}

		wlen = write(th->fd, buf, len);
		if (wlen < 0) {
			if (errno == EINTR) {
				continue;
			}
			if ((errno == EAGAIN || errno == EWOULDBLOCK) &&
			    !force_len) {
				tty_set_blocked(th, true);
				break;
			}
			warn("failed writing to local tty; disabling");
			return -1;
		}

		total_len += wlen;

		if (force_len && total_len >= force_len) {
			break;
		}
	}

	ringbuffer_dequeue_commit(th->rbc, total_len);

	if (force_len) {
		tty_set_fd_blocking(th, false);
	}

	return 0;
}

static enum ringbuffer_poll_ret tty_ringbuffer_poll(void *arg, size_t force_len)
{
	struct tty_handler *th = arg;
	int rc;

	rc = tty_drain_queue(th, force_len);
	if (rc) {
		console_poller_unregister(th->console, th->poller);
		return RINGBUFFER_POLL_REMOVE;
	}

	return RINGBUFFER_POLL_OK;
}

static enum poller_ret tty_poll(struct handler *handler, int events,
				void __attribute__((unused)) * data)
{
	struct tty_handler *th = to_tty_handler(handler);
	uint8_t buf[4096];
	ssize_t len;
	int rc;

	if (events & POLLIN) {
		len = read(th->fd, buf, sizeof(buf));
		if (len <= 0) {
			goto err;
		}

		console_data_out(th->console, buf, len);
	}

	if (events & POLLOUT) {
		tty_set_blocked(th, false);
		rc = tty_drain_queue(th, 0);
		if (rc) {
			goto err;
		}
	}

	return POLLER_OK;

err:
	th->poller = NULL;
	close(th->fd);
	ringbuffer_consumer_unregister(th->rbc);
	return POLLER_REMOVE;
}

static int set_terminal_baud(struct tty_handler *th, const char *tty_name,
			     speed_t speed)
{
	struct termios term_options;

	if (tcgetattr(th->fd, &term_options) < 0) {
		warn("Can't get config for %s", tty_name);
		return -1;
	}

	if (cfsetspeed(&term_options, speed) < 0) {
		warn("Couldn't set speeds for %s", tty_name);
		return -1;
	}

	if (tcsetattr(th->fd, TCSAFLUSH, &term_options) < 0) {
		warn("Couldn't commit terminal options for %s", tty_name);
		return -1;
	}

	return 0;
}

static int make_terminal_raw(struct tty_handler *th, const char *tty_name)
{
	struct termios term_options;

	if (tcgetattr(th->fd, &term_options) < 0) {
		warn("Can't get config for %s", tty_name);
		return -1;
	}

	/* Disable various input and output processing including character
	 * translation, line edit (canonical) mode, flow control, and special signal
	 * generating characters. */
	cfmakeraw(&term_options);

	if (tcsetattr(th->fd, TCSAFLUSH, &term_options) < 0) {
		warn("Couldn't commit terminal options for %s", tty_name);
		return -1;
	}
	printf("Set %s for raw byte handling\n", tty_name);

	return 0;
}

static struct handler *tty_init(const struct handler_type *type
				__attribute__((unused)),
				struct console *console,
				struct config *config __attribute__((unused)))
{
	struct tty_handler *th;
	speed_t desired_speed;
	const char *tty_name;
	const char *tty_baud;
	char *tty_path;
	int rc;

	tty_name = config_get_value(config, "local-tty");
	if (!tty_name) {
		return NULL;
	}

	rc = asprintf(&tty_path, "/dev/%s", tty_name);
	if (!rc) {
		return NULL;
	}

	th = malloc(sizeof(*th));
	if (!th) {
		return NULL;
	}

	th->fd = open(tty_path, O_RDWR | O_NONBLOCK);
	if (th->fd < 0) {
		warn("Can't open %s; disabling local tty", tty_name);
		free(tty_path);
		free(th);
		return NULL;
	}

	free(tty_path);
	th->fd_flags = fcntl(th->fd, F_GETFL, 0);

	tty_baud = config_get_value(config, "local-tty-baud");
	if (tty_baud != NULL) {
		rc = config_parse_baud(&desired_speed, tty_baud);
		if (rc) {
			fprintf(stderr, "%s is not a valid baud rate\n",
				tty_baud);
		} else {
			rc = set_terminal_baud(th, tty_name, desired_speed);
			if (rc) {
				fprintf(stderr,
					"Couldn't set baud rate for %s to %s\n",
					tty_name, tty_baud);
			}
		}
	}

	if (make_terminal_raw(th, tty_name) != 0) {
		fprintf(stderr, "Couldn't make %s a raw terminal\n", tty_name);
	}

	th->poller = console_poller_register(console, &th->handler, tty_poll,
					     NULL, th->fd, POLLIN, NULL);
	th->console = console;
	th->rbc = console_ringbuffer_consumer_register(console,
						       tty_ringbuffer_poll, th);

	return &th->handler;
}

static void tty_fini(struct handler *handler)
{
	struct tty_handler *th = to_tty_handler(handler);
	if (th->poller) {
		console_poller_unregister(th->console, th->poller);
	}
	close(th->fd);
	free(th);
}

static int tty_baudrate(struct handler *handler, speed_t baudrate)
{
	const char *tty_name = "local-tty";
	struct tty_handler *th = to_tty_handler(handler);

	if (baudrate == 0) {
		return -1;
	}

	if (set_terminal_baud(th, tty_name, baudrate) != 0) {
		fprintf(stderr, "Couldn't set baud rate for %s to %d\n",
			tty_name, baudrate);
		return -1;
	}
	return 0;
}

static const struct handler_type tty_handler = {
	.name = "tty",
	.init = tty_init,
	.fini = tty_fini,
	.baudrate = tty_baudrate,
};

console_handler_register(&tty_handler);
