/**
 * 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"

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);
