/**
 * 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 <iniparser/iniparser.h>

#include "config.h"
#include "config-internal.h"

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

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

const char *config_get_value(struct config *config, const char *name)
{
	char buf[CONFIG_MAX_KEY_LENGTH];
	int rc;

	if (!config->dict) {
		return NULL;
	}

	rc = snprintf(buf, CONFIG_MAX_KEY_LENGTH, ":%s", name);
	if (rc < 0) {
		return NULL;
	}

	if ((size_t)rc >= sizeof(buf)) {
		return NULL;
	}

	const char *value = iniparser_getstring(config->dict, buf, NULL);
	if (value && strlen(value) == 0) {
		return NULL;
	}

	return value;
}

struct config *config_init(const char *filename)
{
	struct config *config;
	dictionary *dict;

	if (!filename) {
		filename = config_default_filename;
	}

	if (access(filename, R_OK) == 0) {
		dict = iniparser_load(filename);
		if (!dict) {
			/* Assume this is a parse failure */
			return NULL;
		}
	} else {
		/* If a config file was explicitly specified, then lack of access is always an error */
		if (filename != config_default_filename) {
			warn("Failed to open configuration file at '%s'",
			     filename);
			return NULL;
		}

		/* For the default config path, any result other than not-present is an error */
		if (errno != ENOENT && errno != ENOTDIR) {
			warn("Failed to open configuration file at '%s'",
			     filename);
			return NULL;
		}

		/* Config not present at default path, pretend its empty */
		dict = NULL;
	}

	config = malloc(sizeof(*config));
	if (!config) {
		iniparser_freedict(dict);
		return NULL;
	}

	config->dict = dict;

	return config;
}

void config_fini(struct config *config)
{
	if (!config) {
		return;
	}

	if (config->dict) {
		iniparser_freedict(config->dict);
	}

	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_bytesize(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;
}

/* Default console id if not specified on command line or in config */
#define DEFAULT_CONSOLE_ID "default"

/* Get the console id */
const char *config_resolve_console_id(struct config *config, const char *id_arg)
{
	const char *configured;

	if (id_arg) {
		return id_arg;
	}

	if ((configured = config_get_value(config, "console-id"))) {
		return configured;
	}

	return DEFAULT_CONSOLE_ID;
}
