/**
 * Console server process for OpenBMC
 *
 * 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 <errno.h>
#include <signal.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#include <string.h>
#include <getopt.h>
#include <glob.h>
#include <limits.h>
#include <time.h>
#include <termios.h>

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <poll.h>

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

#define DEV_PTS_PATH "/dev/pts"

/* default size of the shared backlog ringbuffer */
const size_t default_buffer_size = 128ul * 1024ul;

/* state shared with the signal handler */
static volatile sig_atomic_t sigint;

static void usage(const char *progname)
{
	fprintf(stderr,
		"usage: %s [options] <DEVICE>\n"
		"\n"
		"Options:\n"
		"  --config <FILE>\tUse FILE for configuration\n"
		"  --console-id <NAME>\tUse NAME in the UNIX domain socket address\n"
		"",
		progname);
}

static bool console_server_pollfd_reclaimable(struct pollfd *p)
{
	return p->fd == -1 && p->events == 0 && p->revents == ~0;
}

static ssize_t
console_server_find_released_pollfd(struct console_server *server)
{
	for (size_t i = 0; i < server->capacity_pollfds; i++) {
		struct pollfd *p = &server->pollfds[i];
		if (console_server_pollfd_reclaimable(p)) {
			return (ssize_t)i;
		}
	}
	return -1;
}

// returns the index of that pollfd in server->pollfds
// we cannot return a pointer because 'realloc' may move server->pollfds
ssize_t console_server_request_pollfd(struct console_server *server, int fd,
				      short int events)
{
	ssize_t index;
	struct pollfd *pollfd;

	index = console_server_find_released_pollfd(server);

	if (index < 0) {
		const size_t newcap = server->capacity_pollfds + 1;

		struct pollfd *newarr = reallocarray(server->pollfds, newcap,
						     sizeof(struct pollfd));
		if (newarr == NULL) {
			return -1;
		}
		server->pollfds = newarr;

		index = (ssize_t)server->capacity_pollfds;

		server->capacity_pollfds = newcap;
	}

	pollfd = &server->pollfds[index];
	pollfd->fd = fd;
	pollfd->events = events;
	pollfd->revents = 0;

	return index;
}

int console_server_release_pollfd(struct console_server *server,
				  size_t pollfd_index)
{
	if (pollfd_index >= server->capacity_pollfds) {
		return -1;
	}

	struct pollfd *pfd = &server->pollfds[pollfd_index];

	// mark pollfd as reclaimable

	// ignore this file descriptor when calling 'poll'
	// https://www.man7.org/linux/man-pages/man2/poll.2.html
	pfd->fd = -1;
	pfd->events = 0;
	pfd->revents = ~0;

	return 0;
}

/* populates server->tty.dev and server->tty.sysfs_devnode, using the tty kernel name */
static int tty_find_device(struct console_server *server)
{
	char *tty_class_device_link = NULL;
	char *tty_path_input_real = NULL;
	char *tty_device_tty_dir = NULL;
	char *tty_vuart_lpc_addr = NULL;
	char *tty_device_reldir = NULL;
	char *tty_sysfs_devnode = NULL;
	char *tty_kname_real = NULL;
	char *tty_path_input = NULL;
	int rc;

	server->tty.type = TTY_DEVICE_UNDEFINED;

	assert(server->tty.kname);
	if (!strlen(server->tty.kname)) {
		warnx("TTY kname must not be empty");
		rc = -1;
		goto out_free;
	}

	if (server->tty.kname[0] == '/') {
		tty_path_input = strdup(server->tty.kname);
		if (!tty_path_input) {
			rc = -1;
			goto out_free;
		}
	} else {
		rc = asprintf(&tty_path_input, "/dev/%s", server->tty.kname);
		if (rc < 0) {
			goto out_free;
		}
	}

	/* udev may rename the tty name with a symbol link, try to resolve */
	tty_path_input_real = realpath(tty_path_input, NULL);
	if (!tty_path_input_real) {
		warn("Can't find realpath for %s", tty_path_input);
		rc = -1;
		goto out_free;
	}

	/*
	 * Allow hooking obmc-console-server up to PTYs for testing
	 *
	 * https://amboar.github.io/notes/2023/05/02/testing-obmc-console-with-socat.html
	 */
	if (!strncmp(DEV_PTS_PATH, tty_path_input_real, strlen(DEV_PTS_PATH))) {
		server->tty.type = TTY_DEVICE_PTY;
		server->tty.dev = strdup(server->tty.kname);
		rc = server->tty.dev ? 0 : -1;
		goto out_free;
	}

	tty_kname_real = basename(tty_path_input_real);
	if (!tty_kname_real) {
		warn("Can't find real name for %s", server->tty.kname);
		rc = -1;
		goto out_free;
	}

	rc = asprintf(&tty_class_device_link, "/sys/class/tty/%s",
		      tty_kname_real);
	if (rc < 0) {
		goto out_free;
	}

	tty_device_tty_dir = realpath(tty_class_device_link, NULL);
	if (!tty_device_tty_dir) {
		warn("Can't query sysfs for device %s", tty_kname_real);
		rc = -1;
		goto out_free;
	}

	rc = asprintf(&tty_device_reldir, "%s/../../", tty_device_tty_dir);
	if (rc < 0) {
		goto out_free;
	}

	tty_sysfs_devnode = realpath(tty_device_reldir, NULL);
	if (!tty_sysfs_devnode) {
		warn("Can't find parent device for %s", tty_kname_real);
	}

	rc = asprintf(&server->tty.dev, "/dev/%s", tty_kname_real);
	if (rc < 0) {
		goto out_free;
	}

	// Default to non-VUART
	server->tty.type = TTY_DEVICE_UART;

	/* Arbitrarily pick an attribute to differentiate UART vs VUART */
	if (tty_sysfs_devnode) {
		rc = asprintf(&tty_vuart_lpc_addr, "%s/lpc_address",
			      tty_sysfs_devnode);
		if (rc < 0) {
			goto out_free;
		}

		rc = access(tty_vuart_lpc_addr, F_OK);
		if (!rc) {
			server->tty.type = TTY_DEVICE_VUART;
			server->tty.vuart.sysfs_devnode =
				strdup(tty_sysfs_devnode);
		}
	}

	rc = 0;

out_free:
	free(tty_vuart_lpc_addr);
	free(tty_class_device_link);
	free(tty_sysfs_devnode);
	free(tty_device_tty_dir);
	free(tty_device_reldir);
	free(tty_path_input);
	free(tty_path_input_real);
	return rc;
}

static int tty_set_sysfs_attr(struct console_server *server, const char *name,
			      int value)
{
	char *path;
	FILE *fp;
	int rc;

	assert(server->tty.type == TTY_DEVICE_VUART);

	if (!server->tty.vuart.sysfs_devnode) {
		return -1;
	}

	rc = asprintf(&path, "%s/%s", server->tty.vuart.sysfs_devnode, name);
	if (rc < 0) {
		return -1;
	}

	fp = fopen(path, "w");
	if (!fp) {
		warn("Can't access attribute %s on device %s", name,
		     server->tty.kname);
		rc = -1;
		goto out_free;
	}
	setvbuf(fp, NULL, _IONBF, 0);

	rc = fprintf(fp, "0x%x", value);
	if (rc < 0) {
		warn("Error writing to %s attribute of device %s", name,
		     server->tty.kname);
	}
	fclose(fp);

out_free:
	free(path);
	return rc;
}

/**
 * Set termios attributes on the console tty.
 */
void tty_init_termios(struct console_server *server)
{
	struct termios termios;
	int rc;

	rc = tcgetattr(server->tty.fd, &termios);
	if (rc) {
		warn("Can't read tty termios");
		return;
	}

	if (server->tty.type == TTY_DEVICE_UART && server->tty.uart.baud) {
		if (cfsetspeed(&termios, server->tty.uart.baud) < 0) {
			warn("Couldn't set speeds for %s", server->tty.kname);
		}
	}

	/* Set console to raw mode: we don't want any processing to occur on
	 * the underlying terminal input/output.
	 */
	cfmakeraw(&termios);

	rc = tcsetattr(server->tty.fd, TCSANOW, &termios);
	if (rc) {
		warn("Can't set terminal options for %s", server->tty.kname);
	}
}

/**
 * Open and initialise the serial device
 */
static void tty_init_vuart_io(struct console_server *server)
{
	assert(server->tty.type == TTY_DEVICE_VUART);

	if (server->tty.vuart.sirq) {
		tty_set_sysfs_attr(server, "sirq", server->tty.vuart.sirq);
	}

	if (server->tty.vuart.lpc_addr) {
		tty_set_sysfs_attr(server, "lpc_address",
				   server->tty.vuart.lpc_addr);
	}
}

static int tty_init_io(struct console_server *server)
{
	server->tty.fd = open(server->tty.dev, O_RDWR);
	if (server->tty.fd <= 0) {
		warn("Can't open tty %s", server->tty.dev);
		return -1;
	}

	/* Disable character delay. We may want to later enable this when
	 * we detect larger amounts of data
	 */
	fcntl(server->tty.fd, F_SETFL, FNDELAY);

	tty_init_termios(server);

	ssize_t index =
		console_server_request_pollfd(server, server->tty.fd, POLLIN);

	if (index < 0) {
		return -1;
	}

	server->tty_pollfd_index = (size_t)index;

	return 0;
}

static int tty_init_vuart(struct console_server *server, struct config *config)
{
	unsigned long parsed;
	const char *val;
	char *endp;

	assert(server->tty.type == TTY_DEVICE_VUART);

	val = config_get_value(config, "lpc-address");
	if (val) {
		errno = 0;
		parsed = strtoul(val, &endp, 0);
		if (parsed == ULONG_MAX && errno == ERANGE) {
			warn("Cannot interpret 'lpc-address' value as an unsigned long: '%s'",
			     val);
			return -1;
		}

		if (parsed > UINT16_MAX) {
			warn("Invalid LPC address '%s'", val);
			return -1;
		}

		server->tty.vuart.lpc_addr = (uint16_t)parsed;
		if (endp == optarg) {
			warn("Invalid LPC address: '%s'", val);
			return -1;
		}
	}

	val = config_get_value(config, "sirq");
	if (val) {
		errno = 0;
		parsed = strtoul(val, &endp, 0);
		if (parsed == ULONG_MAX && errno == ERANGE) {
			warn("Cannot interpret 'sirq' value as an unsigned long: '%s'",
			     val);
		}

		if (parsed > 16) {
			warn("Invalid LPC SERIRQ: '%s'", val);
		}

		server->tty.vuart.sirq = (int)parsed;
		if (endp == optarg) {
			warn("Invalid sirq: '%s'", val);
		}
	}

	return 0;
}

static int tty_init(struct console_server *server, struct config *config,
		    const char *tty_arg)
{
	const char *val;
	int rc;

	if (tty_arg) {
		server->tty.kname = tty_arg;
	} else if ((val = config_get_value(config, "upstream-tty"))) {
		server->tty.kname = val;
	} else {
		warnx("Error: No TTY device specified");
		return -1;
	}

	rc = tty_find_device(server);
	if (rc) {
		return rc;
	}

	switch (server->tty.type) {
	case TTY_DEVICE_VUART:
		rc = tty_init_vuart(server, config);
		if (rc) {
			return rc;
		}

		tty_init_vuart_io(server);
		break;
	case TTY_DEVICE_UART:
		val = config_get_value(config, "baud");
		if (val) {
			if (config_parse_baud(&server->tty.uart.baud, val)) {
				warnx("Invalid baud rate: '%s'", val);
			}
		}
		break;
	case TTY_DEVICE_PTY:
		break;
	case TTY_DEVICE_UNDEFINED:
	default:
		warnx("Cannot configure unrecognised TTY device");
		return -1;
	}

	return tty_init_io(server);
}

static void tty_fini(struct console_server *server)
{
	if (server->tty_pollfd_index < server->capacity_pollfds) {
		console_server_release_pollfd(server, server->tty_pollfd_index);
		server->tty_pollfd_index = SIZE_MAX;
	}

	if (server->tty.type == TTY_DEVICE_VUART) {
		free(server->tty.vuart.sysfs_devnode);
	}

	free(server->tty.dev);
}

static int write_to_path(const char *path, const char *data)
{
	int rc = 0;
	FILE *f = fopen(path, "w");
	if (!f) {
		return -1;
	}

	if (fprintf(f, "%s", data) < 0) {
		rc = -1;
	}

	if (fclose(f)) {
		rc = -1;
	}

	return rc;
}

#define ASPEED_UART_ROUTING_PATTERN                                            \
	"/sys/bus/platform/drivers/aspeed-uart-routing/*.uart-routing"

static void uart_routing_init(struct config *config)
{
	const char *muxcfg;
	const char *p;
	size_t buflen;
	char *sink;
	char *source;
	char *muxdir;
	char *path;
	glob_t globbuf;

	muxcfg = config_get_value(config, "aspeed-uart-routing");
	if (!muxcfg) {
		return;
	}

	/* Find the driver's sysfs directory */
	if (glob(ASPEED_UART_ROUTING_PATTERN, GLOB_ERR | GLOB_NOSORT, NULL,
		 &globbuf) != 0) {
		warn("Couldn't find uart-routing driver directory, cannot apply config");
		return;
	}
	if (globbuf.gl_pathc != 1) {
		warnx("Found %zd uart-routing driver directories, cannot apply config",
		      globbuf.gl_pathc);
		goto out_free_glob;
	}
	muxdir = globbuf.gl_pathv[0];

	/*
	 * Rather than faff about tracking a bunch of separate buffer sizes,
	 * just use one (worst-case) size for all of them -- +2 for a trailing
	 * NUL and a '/' separator to construct the sysfs file path.
	 */
	buflen = strlen(muxdir) + strlen(muxcfg) + 2;

	sink = malloc(buflen);
	source = malloc(buflen);
	path = malloc(buflen);
	if (!path || !sink || !source) {
		warnx("Out of memory applying uart routing config");
		goto out_free_bufs;
	}

	p = muxcfg;
	while (*p) {
		ssize_t bytes_scanned;

		if (sscanf(p, " %[^:/ \t]:%[^: \t] %zn", sink, source,
			   &bytes_scanned) != 2) {
			warnx("Invalid syntax in aspeed uart config: '%s' not applied",
			      p);
			break;
		}
		p += bytes_scanned;

		/*
		 * Check that the sink name looks reasonable before proceeding
		 * (there are other writable files in the same directory that
		 * we shouldn't be touching, such as 'driver_override' and
		 * 'uevent').
		 */
		if (strncmp(sink, "io", strlen("io")) != 0 &&
		    strncmp(sink, "uart", strlen("uart")) != 0) {
			warnx("Skipping invalid uart routing name '%s' (must be ioN or uartN)",
			      sink);
			continue;
		}

		snprintf(path, buflen, "%s/%s", muxdir, sink);
		if (write_to_path(path, source)) {
			warn("Failed to apply uart-routing config '%s:%s'",
			     sink, source);
		}
	}

out_free_bufs:
	free(path);
	free(source);
	free(sink);
out_free_glob:
	globfree(&globbuf);
}

int console_data_out(struct console *console, const uint8_t *data, size_t len)
{
	return write_buf_to_fd(console->server->tty.fd, data, len);
}

/* Prepare a socket name */
static int set_socket_info(struct console *console, struct config *config,
			   const char *console_id)
{
	ssize_t len;

	/* Get console id */
	console->console_id = config_resolve_console_id(config, console_id);

	/* Get the socket name/path */
	len = console_socket_path(console->socket_name, console->console_id);
	if (len < 0) {
		warn("Failed to set socket path: %s", strerror(errno));
		return EXIT_FAILURE;
	}

	/* Socket name is not a null terminated string hence save the length */
	console->socket_name_len = len;

	return 0;
}

static void handlers_init(struct console *console, struct config *config)
{
	/* NOLINTBEGIN(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
	extern const struct handler_type *const __start_handlers[];
	extern const struct handler_type *const __stop_handlers[];
	/* NOLINTEND(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
	size_t n_types;
	int j = 0;
	size_t i;

	n_types = __stop_handlers - __start_handlers;
	console->handlers = calloc(n_types, sizeof(struct handler *));
	if (!console->handlers) {
		err(EXIT_FAILURE, "malloc(handlers)");
	}

	printf("%zu handler type%s\n", n_types, n_types == 1 ? "" : "s");

	for (i = 0; i < n_types; i++) {
		const struct handler_type *type = __start_handlers[i];
		struct handler *handler;

		/* Should be picked up at build time by
		 * console_handler_register, but check anyway
		 */
		if (!type->init || !type->fini) {
			errx(EXIT_FAILURE,
			     "invalid handler type %s: no init() / fini()",
			     type->name);
		}

		handler = type->init(type, console, config);

		printf("  console '%s': handler %s [%sactive]\n",
		       console->console_id, type->name, handler ? "" : "in");

		if (handler) {
			handler->type = type;
			console->handlers[j++] = handler;
		}
	}

	console->n_handlers = j;
}

static void handlers_fini(struct console *console)
{
	struct handler *handler;
	int i;

	for (i = 0; i < console->n_handlers; i++) {
		handler = console->handlers[i];
		handler->type->fini(handler);
	}

	free(console->handlers);
	console->handlers = NULL;
	console->n_handlers = 0;
}

static int get_current_time(struct timeval *tv)
{
	struct timespec t;
	int rc;

	/*
	 * We use clock_gettime(CLOCK_MONOTONIC) so we're immune to
	 * local time changes. However, a struct timeval is more
	 * convenient for calculations, so convert to that.
	 */
	rc = clock_gettime(CLOCK_MONOTONIC, &t);
	if (rc) {
		return rc;
	}

	tv->tv_sec = t.tv_sec;
	tv->tv_usec = t.tv_nsec / 1000;

	return 0;
}

struct ringbuffer_consumer *
console_ringbuffer_consumer_register(struct console *console,
				     ringbuffer_poll_fn_t poll_fn, void *data)
{
	return ringbuffer_consumer_register(console->rb, poll_fn, data);
}

struct poller *console_poller_register(struct console *console,
				       struct handler *handler,
				       poller_event_fn_t poller_fn,
				       poller_timeout_fn_t timeout_fn, int fd,
				       int events, void *data)
{
	struct poller *poller;
	long n;

	const ssize_t index = console_server_request_pollfd(
		console->server, fd, (short)(events & 0x7fff));
	if (index < 0) {
		fprintf(stderr, "Error requesting pollfd\n");
		return NULL;
	}

	poller = malloc(sizeof(*poller));
	// TODO: check for error case of malloc here and release previously requested pollfd
	poller->remove = false;
	poller->handler = handler;
	poller->event_fn = poller_fn;
	poller->timeout_fn = timeout_fn;
	timerclear(&poller->timeout);
	poller->data = data;
	poller->pollfd_index = index;

	/* add one to our pollers array */
	n = console->n_pollers++;
	/*
	 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a
	 * pointer type.
	 */
	/* NOLINTBEGIN(bugprone-sizeof-expression) */
	console->pollers = reallocarray(console->pollers, console->n_pollers,
					sizeof(*console->pollers));
	// TODO: check for the error case of reallocarray and release previously requested pollfd
	/* NOLINTEND(bugprone-sizeof-expression) */

	console->pollers[n] = poller;

	return poller;
}

void console_poller_unregister(struct console *console, struct poller *poller)
{
	int i;

	/* find the entry in our pollers array */
	for (i = 0; i < console->n_pollers; i++) {
		if (console->pollers[i] == poller) {
			break;
		}
	}

	assert(i < console->n_pollers);

	console->n_pollers--;

	/*
	 * Remove the item from the pollers array...
	 *
	 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a
	 * pointer type.
	 */
	/* NOLINTBEGIN(bugprone-sizeof-expression) */
	memmove(&console->pollers[i], &console->pollers[i + 1],
		sizeof(*console->pollers) * (console->n_pollers - i));

	if (console->n_pollers == 0) {
		free(console->pollers);
		console->pollers = NULL;
	} else {
		console->pollers = reallocarray(console->pollers,
						console->n_pollers,
						sizeof(*console->pollers));
	}
	/* NOLINTEND(bugprone-sizeof-expression) */

	console_server_release_pollfd(console->server, poller->pollfd_index);

	free(poller);
}

void console_poller_set_events(struct console *console, struct poller *poller,
			       int events)
{
	console->server->pollfds[poller->pollfd_index].events =
		(short)(events & 0x7fff);
}

void console_poller_set_timeout(struct console *console __attribute__((unused)),
				struct poller *poller, const struct timeval *tv)
{
	struct timeval now;
	int rc;

	rc = get_current_time(&now);
	if (rc) {
		return;
	}

	timeradd(&now, tv, &poller->timeout);
}

static long get_poll_timeout(struct console *console, struct timeval *cur_time)
{
	struct timeval *earliest;
	struct timeval interval;
	struct poller *poller;
	int i;

	earliest = NULL;

	for (i = 0; i < console->n_pollers; i++) {
		poller = console->pollers[i];

		if (poller->timeout_fn && timerisset(&poller->timeout) &&
		    (!earliest ||
		     (earliest && timercmp(&poller->timeout, earliest, <)))) {
			// poller is buffering data and needs the poll
			// function to timeout.
			earliest = &poller->timeout;
		}
	}

	if (earliest) {
		if (timercmp(earliest, cur_time, >)) {
			/* recalculate the timeout period, time period has
			 * not elapsed */
			timersub(earliest, cur_time, &interval);
			return ((interval.tv_sec * 1000) +
				(interval.tv_usec / 1000));
		} /* return from poll immediately */
		return 0;

	} /* poll indefinitely */
	return -1;
}

static int call_pollers(struct console *console, struct timeval *cur_time)
{
	struct poller *poller;
	struct pollfd *pollfd;
	enum poller_ret prc;
	int i;
	int rc;

	rc = 0;

	/*
	 * Process poll events by iterating through the pollers and pollfds
	 * in-step, calling any pollers that we've found revents for.
	 */
	for (i = 0; i < console->n_pollers; i++) {
		poller = console->pollers[i];
		pollfd = &console->server->pollfds[poller->pollfd_index];
		if (pollfd->fd < 0) {
			// pollfd has already been released
			continue;
		}

		prc = POLLER_OK;

		/* process pending events... */
		if (pollfd->revents) {
			prc = poller->event_fn(poller->handler, pollfd->revents,
					       poller->data);
			if (prc == POLLER_EXIT) {
				rc = -1;
			} else if (prc == POLLER_REMOVE) {
				poller->remove = true;
			}
		}

		if ((prc == POLLER_OK) && poller->timeout_fn &&
		    timerisset(&poller->timeout) &&
		    timercmp(&poller->timeout, cur_time, <=)) {
			/* One of the ringbuffer consumers is buffering the
			data stream. The amount of idle time the consumer
			desired has expired.  Process the buffered data for
			transmission. */
			timerclear(&poller->timeout);
			prc = poller->timeout_fn(poller->handler, poller->data);
			if (prc == POLLER_EXIT) {
				rc = -1;
			} else if (prc == POLLER_REMOVE) {
				poller->remove = true;
			}
		}
	}

	/**
	 * Process deferred removals; restarting each time we unregister, as
	 * the array will have changed
	 */
	for (;;) {
		bool removed = false;

		for (i = 0; i < console->n_pollers; i++) {
			poller = console->pollers[i];
			if (poller->remove) {
				console_poller_unregister(console, poller);
				removed = true;
				break;
			}
		}
		if (!removed) {
			break;
		}
	}

	return rc;
}

static void sighandler(int signal)
{
	if (signal == SIGINT) {
		sigint = 1;
	}
}

static int run_console_per_console(struct console *console, size_t buf_size,
				   struct timeval *tv)
{
	int rc;

	if (console->rb->size < buf_size) {
		fprintf(stderr, "Ringbuffer size should be greater than %zuB\n",
			buf_size);
		return -1;
	}

	if (sigint) {
		warnx("Received interrupt, exiting\n");
		return -1;
	}

	/* ... and then the pollers */
	rc = call_pollers(console, tv);
	if (rc) {
		return -1;
	}

	return 0;
}

static int run_console_iteration(struct console_server *server)
{
	struct timeval tv;
	uint8_t buf[4096];
	long timeout;
	ssize_t rc;

	rc = get_current_time(&tv);
	if (rc) {
		warn("Failed to read current time");
		return -1;
	}

	timeout = get_poll_timeout(server->active, &tv);

	rc = poll(server->pollfds, server->capacity_pollfds, (int)timeout);

	if (sigint) {
		warnx("Received interrupt, exiting\n");
		return -1;
	}

	if (rc < 0) {
		if (errno == EINTR) {
			return 0;
		}
		warn("poll error");
		return -1;
	}

	/* process internal fd first */
	if (server->pollfds[server->tty_pollfd_index].revents) {
		rc = read(server->tty.fd, buf, sizeof(buf));
		if (rc <= 0) {
			warn("Error reading from tty device");
			return -1;
		}

		rc = ringbuffer_queue(server->active->rb, buf, rc);
		if (rc) {
			return -1;
		}
	}

	// process dbus
	struct pollfd *dbus_pollfd =
		&(server->pollfds[server->dbus_pollfd_index]);
	if (dbus_pollfd->revents) {
		sd_bus_process(server->bus, NULL);
	}

	for (size_t i = 0; i < server->n_consoles; i++) {
		struct console *console = server->consoles[i];

		rc = run_console_per_console(console, sizeof(buf), &tv);
		if (rc != 0) {
			return -1;
		}
	}

	return 0;
}

int run_server(struct console_server *server)
{
	sighandler_t sighandler_save;
	ssize_t rc = 0;

	if (server->n_consoles == 0) {
		warnx("no console configured for this server");
		return -1;
	}

	sighandler_save = signal(SIGINT, sighandler);
	for (;;) {
		rc = run_console_iteration(server);
		if (rc) {
			break;
		}
	}
	signal(SIGINT, sighandler_save);

	return rc ? -1 : 0;
}

static const struct option options[] = {
	{ "config", required_argument, 0, 'c' },
	{ "console-id", required_argument, 0, 'i' },
	{ 0, 0, 0, 0 },
};

static struct console *console_init(struct console_server *server,
				    struct config *config,
				    const char *console_id)
{
	size_t buffer_size = default_buffer_size;
	const char *buffer_size_str = NULL;
	int rc;

	struct console *console = calloc(1, sizeof(struct console));
	if (console == NULL) {
		return NULL;
	}

	console->server = server;
	console->console_id = console_id;

	buffer_size_str =
		config_get_section_value(config, console_id, "ringbuffer-size");

	if (!buffer_size_str) {
		buffer_size_str = config_get_value(config, "ringbuffer-size");
	}

	if (buffer_size_str) {
		rc = config_parse_bytesize(buffer_size_str, &buffer_size);
		if (rc) {
			warn("Invalid ringbuffer-size. Default to %zukB",
			     buffer_size >> 10);
		}
	}

	console->rb = ringbuffer_init(buffer_size);
	if (!console->rb) {
		goto cleanup_console;
	}

	if (set_socket_info(console, config, console_id)) {
		warnx("set_socket_info failed");
		goto cleanup_rb;
	}

	rc = dbus_init(console, config);
	if (rc != 0) {
		goto cleanup_rb;
	}

	handlers_init(console, config);

	return console;

cleanup_rb:
	free(console->rb);
cleanup_console:
	free(console);

	return NULL;
}

static void console_fini(struct console *console)
{
	handlers_fini(console);
	ringbuffer_fini(console->rb);
	free(console->pollers);
	free(console);
}

// 'opt_console_id' may be NULL
static int console_server_add_console(struct console_server *server,
				      struct config *config,
				      const char *opt_console_id)
{
	const char *console_id;
	struct console *console;

	console_id = config_resolve_console_id(config, opt_console_id);

	struct console **tmp = reallocarray(server->consoles,
					    server->n_consoles + 1,
					    sizeof(struct console *));
	if (tmp == NULL) {
		warnx("could not realloc server->consoles");
		return -1;
	}
	server->consoles = tmp;

	console = console_init(server, config, console_id);
	if (console == NULL) {
		warnx("console_init failed");
		return -1;
	}

	server->consoles[server->n_consoles++] = console;

	return 0;
}

// returns NULL on error
static struct console *
console_server_add_consoles(struct console_server *server,
			    const char *arg_console_id)
{
	int rc;

	const int nsections = config_count_sections(server->config);
	if (nsections < 0) {
		return NULL;
	}

	if (nsections == 0) {
		const char *console_id = arg_console_id;

		rc = console_server_add_console(server, server->config,
						console_id);
		if (rc != 0) {
			return NULL;
		}
	}

	for (int i = 0; i < nsections; i++) {
		const char *console_id =
			config_get_section_name(server->config, i);

		if (console_id == NULL) {
			warnx("no console id provided\n");
			return NULL;
		}

		rc = console_server_add_console(server, server->config,
						console_id);
		if (rc != 0) {
			return NULL;
		}
	}

	const char *initially_active =
		config_get_value(server->config, "active-console");
	if (!initially_active) {
		return server->consoles[0];
	}

	printf("setting console-id '%s' as the initially active console\n",
	       initially_active);

	for (size_t i = 0; i < server->n_consoles; i++) {
		struct console *console = server->consoles[i];

		if (strcmp(console->console_id, initially_active) == 0) {
			return console;
		}
	}

	warnx("'active-console' '%s' not found among console ids\n",
	      initially_active);

	return NULL;
}

int console_server_init(struct console_server *server,
			const char *config_filename,
			const char *config_tty_kname, const char *console_id)
{
	int rc;
	memset(server, 0, sizeof(struct console_server));

	server->tty_pollfd_index = -1;

	server->config = config_init(config_filename);
	if (server->config == NULL) {
		return -1;
	}

	uart_routing_init(server->config);

	rc = tty_init(server, server->config, config_tty_kname);
	if (rc != 0) {
		warnx("error during tty_init, exiting.\n");
		return -1;
	}

	rc = dbus_server_init(server);
	if (rc != 0) {
		warnx("error during dbus init for console server");
		return -1;
	}

	server->active = console_server_add_consoles(server, console_id);
	if (server->active == NULL) {
		return -1;
	}

	return 0;
}

void console_server_fini(struct console_server *server)
{
	for (size_t i = 0; i < server->n_consoles; i++) {
		console_fini(server->consoles[i]);
	}

	free(server->consoles);
	dbus_server_fini(server);
	tty_fini(server);
	free(server->pollfds);
	config_fini(server->config);
}

int main(int argc, char **argv)
{
	const char *config_filename = NULL;
	const char *config_tty_kname = NULL;
	const char *console_id = NULL;
	struct console_server server = { 0 };
	int rc = 0;

	for (;;) {
		int c;
		int idx;

		c = getopt_long(argc, argv, "c:i:", options, &idx);
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'c':
			config_filename = optarg;
			break;
		case 'i':
			console_id = optarg;
			break;
		case 'h':
		case '?':
			usage(argv[0]);
			return EXIT_SUCCESS;
		}
	}

	if (optind < argc) {
		config_tty_kname = argv[optind];
	} else {
		errx(EXIT_FAILURE, "no tty device path has been provided\n");
	}

	rc = console_server_init(&server, config_filename, config_tty_kname,
				 console_id);

	if (rc == 0) {
		rc = run_server(&server);
	}

	console_server_fini(&server);

	return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
