/**
 * 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-internal.h"
#include "config.h"
#include "util.h"

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 || !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;
}

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

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

	if ((size_t)rc >= sizeof(buf)) {
		// error / key too long for the buffer
		warnx("config: section:key too long for buffer: '%s':'%s'",
		      secname, name);
		return NULL;
	}

	return iniparser_getstring(config->dict, buf, NULL);
}

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

int config_count_sections(struct config *config)
{
	return iniparser_getnsec(config->dict);
}

const char *config_get_section_name(struct config *config, int i)
{
	return iniparser_getsecname(config->dict, i);
}
