// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
 * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
 */

#include "env-lib.h"
#include <env.h>
#include <log.h>
#include <vsprintf.h>
#include <linux/errno.h>
#include <linux/printk.h>

#define MAX_CMD_LEN	25

static void env_clear_common(u32 index, const struct env_map_common *map)
{
	map[index].val->val = 0;
	map[index].val->set = false;
}

static int env_read_common(u32 index, const struct env_map_common *map)
{
	u32 val;

	if (!env_get_yesno(map[index].env_name)) {
		if (map[index].type == ENV_HEX) {
			val = (u32)env_get_hex(map[index].env_name, 0);
			debug("ENV: %s: = %#x\n", map[index].env_name, val);
		} else {
			val = (u32)env_get_ulong(map[index].env_name, 10, 0);
			debug("ENV: %s: = %d\n", map[index].env_name, val);
		}

		map[index].val->val = val;
		map[index].val->set = true;
	}

	return 0;
}

static void env_clear_core(u32 index, const struct env_map_percpu *map)
{
	for (u32 i = 0; i < NR_CPUS; i++) {
		(*map[index].val)[i].val = 0;
		(*map[index].val)[i].set = false;
	}
}

static int env_read_core(u32 index, const struct env_map_percpu *map)
{
	u32 val;
	char command[MAX_CMD_LEN];

	for (u32 i = 0; i < NR_CPUS; i++) {
		sprintf(command, "%s_%u", map[index].env_name, i);
		if (!env_get_yesno(command)) {
			if (map[index].type == ENV_HEX) {
				val = (u32)env_get_hex(command, 0);
				debug("ENV: %s: = %#x\n", command, val);
			} else {
				val = (u32)env_get_ulong(command, 10, 0);
				debug("ENV: %s: = %d\n", command, val);
			}

			(*map[index].val)[i].val = val;
			(*map[index].val)[i].set = true;
		}
	}

	return 0;
}

static int env_validate_common(u32 index, const struct env_map_common *map)
{
	u32 value = map[index].val->val;
	bool set = map[index].val->set;
	u32 min = map[index].min;
	u32 max = map[index].max;

	/* Check if environment is mandatory */
	if (map[index].mandatory && !set) {
		pr_err("Variable \'%s\' is mandatory, but it is not defined\n",
		       map[index].env_name);

		return -EINVAL;
	}

	/* Check environment boundary */
	if (set && (value < min || value > max)) {
		if (map[index].type == ENV_HEX)
			pr_err("Variable \'%s\' must be between %#x and %#x\n",
			       map[index].env_name, min, max);
		else
			pr_err("Variable \'%s\' must be between %u and %u\n",
			       map[index].env_name, min, max);

		return -EINVAL;
	}

	return 0;
}

static int env_validate_core(u32 index, const struct env_map_percpu *map,
			     bool (*cpu_used)(u32))
{
	u32 value;
	bool set;
	bool mandatory = map[index].mandatory;
	u32 min, max;

	for (u32 i = 0; i < NR_CPUS; i++) {
		set = (*map[index].val)[i].set;
		value = (*map[index].val)[i].val;

		/* Check if environment is mandatory */
		if (cpu_used(i) && mandatory && !set) {
			pr_err("CPU %u is used, but \'%s_%u\' is not defined\n",
			       i, map[index].env_name, i);

			return -EINVAL;
		}

		min = map[index].min[i];
		max = map[index].max[i];

		/* Check environment boundary */
		if (set && (value < min || value > max)) {
			if (map[index].type == ENV_HEX)
				pr_err("Variable \'%s_%u\' must be between %#x and %#x\n",
				       map[index].env_name, i, min, max);
			else
				pr_err("Variable \'%s_%u\' must be between %d and %d\n",
				       map[index].env_name, i, min, max);

			return -EINVAL;
		}
	}

	return 0;
}

void envs_cleanup_core(const struct env_map_percpu *map)
{
	/* Cleanup env struct first */
	for (u32 i = 0; map[i].env_name; i++)
		env_clear_core(i, map);
}

void envs_cleanup_common(const struct env_map_common *map)
{
	/* Cleanup env struct first */
	for (u32 i = 0; map[i].env_name; i++)
		env_clear_common(i, map);
}

int envs_read_common(const struct env_map_common *map)
{
	int ret;

	for (u32 i = 0; map[i].env_name; i++) {
		ret = env_read_common(i, map);
		if (ret)
			return ret;
	}

	return 0;
}

int envs_validate_common(const struct env_map_common *map)
{
	int ret;

	for (u32 i = 0; map[i].env_name; i++) {
		ret = env_validate_common(i, map);
		if (ret)
			return ret;
	}

	return 0;
}

int envs_read_validate_common(const struct env_map_common *map)
{
	int ret;

	envs_cleanup_common(map);

	ret = envs_read_common(map);
	if (ret)
		return ret;

	ret = envs_validate_common(map);
	if (ret)
		return ret;

	return 0;
}

int envs_read_validate_core(const struct env_map_percpu *map,
			    bool (*cpu_used)(u32))
{
	int ret;

	envs_cleanup_core(map);

	for (u32 i = 0; map[i].env_name; i++) {
		ret = env_read_core(i, map);
		if (ret)
			return ret;
	}

	for (u32 i = 0; map[i].env_name; i++) {
		ret = env_validate_core(i, map, cpu_used);
		if (ret)
			return ret;
	}

	return 0;
}

int envs_process_and_validate(const struct env_map_common *common,
			      const struct env_map_percpu *core,
			      bool (*cpu_used)(u32))
{
	int ret;

	ret = envs_read_validate_common(common);
	if (ret)
		return ret;

	ret = envs_read_validate_core(core, cpu_used);
	if (ret)
		return ret;

	return 0;
}

static int args_envs_read_search(const struct env_map_common *map,
				 int argc, char *const argv[])
{
	for (int i = 0; map[i].env_name; i++) {
		if (!strcmp(argv[0], map[i].env_name))
			return i;
	}

	pr_err("Unexpected argument '%s', can't parse\n", argv[0]);

	return -ENOENT;
}

static int arg_read_set(const struct env_map_common *map, u32 i, int argc,
			char *const argv[])
{
	char *endp = argv[1];

	if (map[i].type == ENV_HEX)
		map[i].val->val = hextoul(argv[1], &endp);
	else
		map[i].val->val = dectoul(argv[1], &endp);

	map[i].val->set = true;

	if (*endp == '\0')
		return 0;

	pr_err("Unexpected argument '%s', can't parse\n", argv[1]);

	map[i].val->set = false;

	return -EINVAL;
}

int args_envs_enumerate(const struct env_map_common *map, int enum_by,
			int argc, char *const argv[])
{
	u32 i;

	if (argc % enum_by) {
		pr_err("unexpected argument number: %d\n", argc);
		return -EINVAL;
	}

	while (argc > 0) {
		i = args_envs_read_search(map, argc, argv);
		if (i < 0)
			return i;

		debug("ARG: found '%s' with index %d\n", map[i].env_name, i);

		if (i < 0) {
			pr_err("unknown arg: %s\n", argv[0]);
			return -EINVAL;
		}

		if (arg_read_set(map, i, argc, argv))
			return -EINVAL;

		debug("ARG: value.s '%s' == %#x\n", argv[1], map[i].val->val);

		argc -= enum_by;
		argv += enum_by;
	}

	return 0;
}
