/**
 * 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 <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <termios.h> /* for speed_t */
#include <unistd.h>

#include <sys/mman.h>
#include <sys/stat.h>
#include "console-server.h"

static const char *config_default_filename = SYSCONFDIR "/obmc-console.conf";

struct config_item {
	char *name;
	char *value;
	struct config_item *next;
};

struct config {
	struct config_item *items;
};

const char *config_get_value(struct config *config, const char *name)
{
	struct config_item *item;

	for (item = config->items; item; item = item->next) {
		if (!strcasecmp(item->name, name)) {
			return item->value;
		}
	}

	return NULL;
}

static void config_parse(struct config *config, char *buf)
{
	struct config_item *item;
	char *name;
	char *value;
	char *p;
	char *line;

	for (p = NULL, line = strtok_r(buf, "\n", &p); line;
	     line = strtok_r(NULL, "\n", &p)) {
		int rc;

		/* trim leading space */
		for (; *line == ' ' || *line == '\t'; line++) {
			;
		}

		/* skip comments */
		if (*line == '#') {
			continue;
		}

		name = malloc(strlen(line));
		value = malloc(strlen(line));
		if (name && value) {
			rc = sscanf(line, "%[^ =] = %s ", name, value);
		} else {
			rc = -ENOMEM;
		}

		if (rc != 2) {
			free(name);
			free(value);
			continue;
		}

		/* create a new item and add to our list */
		item = malloc(sizeof(*item));
		item->name = name;
		item->value = value;
		item->next = config->items;
		config->items = item;
	}
}

static struct config *config_init_fd(int fd, const char *filename)
{
	struct config *config;
	size_t size;
	size_t len;
	ssize_t rc;
	char *buf;

	size = 4096;
	len = 0;
	buf = malloc(size + 1);
	config = NULL;

	for (;;) {
		rc = read(fd, buf + len, size - len);
		if (rc < 0) {
			warn("Can't read from configuration file %s", filename);
			goto out_free;

		} else if (!rc) {
			break;
		}
		len += rc;
		if (len == size) {
			size <<= 1;
			buf = realloc(buf, size + 1);
		}
	}
	buf[len] = '\0';

	config = malloc(sizeof(*config));
	config->items = NULL;

	config_parse(config, buf);

out_free:
	free(buf);
	return config;
}

struct config *config_init(const char *filename)
{
	struct config *config;
	int fd;

	if (!filename) {
		filename = config_default_filename;
	}

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		warn("Can't open configuration file %s", filename);
		return NULL;
	}

	config = config_init_fd(fd, filename);

	close(fd);

	return config;
}

void config_fini(struct config *config)
{
	struct config_item *item;
	struct config_item *next;

	for (item = config->items; item; item = next) {
		next = item->next;
		free(item->name);
		free(item->value);
		free(item);
	}

	free(config);
}

struct terminal_speed_name {
	speed_t speed;
	uint32_t baud;
	const char *name;
};

#define TERM_SPEED(x)                                                          \
	{                                                                      \
		B##x, x, #x                                                    \
	}

// clang-format off
static const struct terminal_speed_name terminal_speeds[] = {
	TERM_SPEED(50),
	TERM_SPEED(75),
	TERM_SPEED(110),
	TERM_SPEED(134),
	TERM_SPEED(150),
	TERM_SPEED(200),
	TERM_SPEED(300),
	TERM_SPEED(600),
	TERM_SPEED(1200),
	TERM_SPEED(1800),
	TERM_SPEED(2400),
	TERM_SPEED(4800),
	TERM_SPEED(9600),
	TERM_SPEED(19200),
	TERM_SPEED(38400),
	TERM_SPEED(57600),
	TERM_SPEED(115200),
	TERM_SPEED(230400),
	TERM_SPEED(460800),
	TERM_SPEED(500000),
	TERM_SPEED(576000),
	TERM_SPEED(921600),
	TERM_SPEED(1000000),
	TERM_SPEED(1152000),
	TERM_SPEED(1500000),
	TERM_SPEED(2000000),
	TERM_SPEED(2500000),
	TERM_SPEED(3000000),
	TERM_SPEED(3500000),
	TERM_SPEED(4000000),
};
// clang-format on

int config_parse_baud(speed_t *speed, const char *baud_string)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(terminal_speeds); i++) {
		if (strcmp(baud_string, terminal_speeds[i].name) == 0) {
			*speed = terminal_speeds[i].speed;
			return 0;
		}
	}
	return -1;
}

uint32_t parse_baud_to_int(speed_t speed)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(terminal_speeds); i++) {
		if (terminal_speeds[i].speed == speed) {
			return terminal_speeds[i].baud;
		}
	}
	return 0;
}

speed_t parse_int_to_baud(uint32_t baud)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(terminal_speeds); i++) {
		if (terminal_speeds[i].baud == baud) {
			return terminal_speeds[i].speed;
		}
	}
	return 0;
}

int config_parse_logsize(const char *size_str, size_t *size)
{
	struct size_suffix_shift {
		/* Left shiftwidth corresponding to the suffix. */
		size_t shiftwidth;
		int unit;
	};

	const struct size_suffix_shift suffixes[] = {
		{ 10, 'k' },
		{ 20, 'M' },
		{ 30, 'G' },
	};
	const size_t num_suffixes =
		sizeof(suffixes) / sizeof(struct size_suffix_shift);
	size_t logsize;
	char *suffix;
	size_t i;

	if (!size_str) {
		return -1;
	}

	logsize = strtoul(size_str, &suffix, 0);
	if (logsize == 0 || logsize >= UINT32_MAX || suffix == size_str) {
		return -1;
	}

	/* Ignore spaces between number and suffix */
	while (*suffix && isspace(*suffix)) {
		suffix++;
	}

	for (i = 0; i < num_suffixes; i++) {
		if (*suffix == suffixes[i].unit) {
			/*
			 * If logsize overflows, probably something was wrong.
			 * Return instead of clamping to an arbitrary value.
			 */
			if (logsize > (UINT32_MAX >> suffixes[i].shiftwidth)) {
				return -1;
			}

			logsize <<= suffixes[i].shiftwidth;
			suffix++;
			break;
		}
	}

	/* Allow suffix like 'kB' */
	while (*suffix && (tolower(*suffix) == 'b' || isspace(*suffix))) {
		suffix++;
	}

	if (*suffix) {
		warn("Invalid suffix!");
		return -1;
	}

	*size = logsize;
	return 0;
}

#ifdef CONFIG_TEST
int main(void)
{
	struct config_item *item;
	struct config *config;

	config = config_init_fd(STDIN_FILENO, "<stdin>");
	if (!config)
		return EXIT_FAILURE;

	for (item = config->items; item; item = item->next)
		printf("%s: %s\n", item->name, item->value);

	config_fini(config);

	return EXIT_SUCCESS;
}
#endif
