/*
 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
 * Released under the terms of the GNU GPL v2.0.
 */

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>

#define LKC_DIRECT_LINK
#include "lkc.h"

struct symbol symbol_yes = {
	name: "y",
	curr: { "y", yes },
	flags: SYMBOL_YES|SYMBOL_VALID,
}, symbol_mod = {
	name: "m",
	curr: { "m", mod },
	flags: SYMBOL_MOD|SYMBOL_VALID,
}, symbol_no = {
	name: "n",
	curr: { "n", no },
	flags: SYMBOL_NO|SYMBOL_VALID,
}, symbol_empty = {
	name: "",
	curr: { "", no },
	flags: SYMBOL_VALID,
};

int sym_change_count;
struct symbol *modules_sym;

void sym_add_default(struct symbol *sym, const char *def)
{
	struct property *prop = create_prop(P_DEFAULT);
	struct property **propp;

	prop->sym = sym;
	prop->def = sym_lookup(def, 1);

	/* append property to the prop list of symbol */
	if (prop->sym) {
		for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
			;
		*propp = prop;
	}
}

void sym_init(void)
{
	struct symbol *sym;
	struct utsname uts;
	char *p;
	static bool inited = false;

	if (inited)
		return;
	inited = true;

	uname(&uts);

#if 0
	sym = sym_lookup("ARCH", 0);
	sym->type = S_STRING;
	sym->flags |= SYMBOL_AUTO;
	p = getenv("ARCH");
	if (p)
		sym_add_default(sym, p);
#endif

	sym = sym_lookup("VERSION", 0);
	sym->type = S_STRING;
	sym->flags |= SYMBOL_AUTO;
	p = getenv("VERSION");
	if (p)
		sym_add_default(sym, p);

#if 0
	sym = sym_lookup("UNAME_RELEASE", 0);
	sym->type = S_STRING;
	sym->flags |= SYMBOL_AUTO;
	sym_add_default(sym, uts.release);
#endif

	sym = sym_lookup("TARGET_ARCH", 0);
	sym->type = S_STRING;
	sym->flags |= SYMBOL_AUTO;
	p = getenv("TARGET_ARCH");
	if (p)
		sym_add_default(sym, p);
}

int sym_get_type(struct symbol *sym)
{
	int type = sym->type;
	if (type == S_TRISTATE) {
		if (sym_is_choice_value(sym) && sym->visible == yes)
			type = S_BOOLEAN;
		else {
			sym_calc_value(modules_sym);
			if (S_TRI(modules_sym->curr) == no)
				type = S_BOOLEAN;
		}
	}
	return type;
}

const char *sym_type_name(int type)
{
	switch (type) {
	case S_BOOLEAN:
		return "boolean";
	case S_TRISTATE:
		return "tristate";
	case S_INT:
		return "integer";
	case S_HEX:
		return "hex";
	case S_STRING:
		return "string";
	case S_UNKNOWN:
		return "unknown";
	}
	return "???";
}

struct property *sym_get_choice_prop(struct symbol *sym)
{
	struct property *prop;

	for_all_choices(sym, prop)
		return prop;
	return NULL;
}

struct property *sym_get_default_prop(struct symbol *sym)
{
	struct property *prop;
	tristate visible;

	for_all_defaults(sym, prop) {
		visible = E_CALC(prop->visible);
		if (visible != no)
			return prop;
	}
	return NULL;
}

void sym_calc_visibility(struct symbol *sym)
{
	struct property *prop;
	tristate visible, oldvisible;

	/* any prompt visible? */
	oldvisible = sym->visible;
	visible = no;
	for_all_prompts(sym, prop)
		visible = E_OR(visible, E_CALC(prop->visible));
	if (oldvisible != visible) {
		sym->visible = visible;
		sym->flags |= SYMBOL_CHANGED;
	}
}

void sym_calc_value(struct symbol *sym)
{
	struct symbol_value newval, oldval;
	struct property *prop, *def_prop;
	struct symbol *def_sym;
	struct expr *e;

	if (sym->flags & SYMBOL_VALID)
		return;

	oldval = sym->curr;

	switch (sym->type) {
	case S_INT:
	case S_HEX:
	case S_STRING:
		newval = symbol_empty.curr;
		break;
	case S_BOOLEAN:
	case S_TRISTATE:
		newval = symbol_no.curr;
		break;
	default:
		S_VAL(newval) = sym->name;
		S_TRI(newval) = no;
		if (sym->flags & SYMBOL_CONST) {
			goto out;
		}
		//newval = symbol_empty.curr;
		// generate warning somewhere here later
		//S_TRI(newval) = yes;
		goto out;
	}
	sym->flags |= SYMBOL_VALID;
	if (!sym_is_choice_value(sym))
		sym->flags &= ~SYMBOL_WRITE;

	sym_calc_visibility(sym);

	/* set default if recursively called */
	sym->curr = newval;

	if (sym->visible != no) {
		sym->flags |= SYMBOL_WRITE;
		if (!sym_has_value(sym)) {
			if (!sym_is_choice(sym)) {
				prop = sym_get_default_prop(sym);
				if (prop) {
					sym_calc_value(prop->def);
					newval = prop->def->curr;
				}
			}
		} else
			newval = sym->def;

		S_TRI(newval) = E_AND(S_TRI(newval), sym->visible);
		/* if the symbol is visible and not optionial,
		 * possibly ignore old user choice. */
		if (!sym_is_optional(sym) && S_TRI(newval) == no)
			S_TRI(newval) = sym->visible;
		if (sym_is_choice_value(sym) && sym->visible == yes) {
			prop = sym_get_choice_prop(sym);
			S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no;
		}
	} else {
		prop = sym_get_default_prop(sym);
		if (prop) {
			sym->flags |= SYMBOL_WRITE;
			sym_calc_value(prop->def);
			newval = prop->def->curr;
		}
	}

	switch (sym_get_type(sym)) {
	case S_TRISTATE:
		if (S_TRI(newval) != mod)
			break;
		sym_calc_value(modules_sym);
		if (S_TRI(modules_sym->curr) == no)
			S_TRI(newval) = yes;
		break;
	case S_BOOLEAN:
		if (S_TRI(newval) == mod)
			S_TRI(newval) = yes;
	}

out:
	sym->curr = newval;

	if (sym_is_choice(sym) && S_TRI(newval) == yes) {
		def_sym = S_VAL(sym->def);
		if (def_sym) {
			sym_calc_visibility(def_sym);
			if (def_sym->visible == no)
				def_sym = NULL;
		}
		if (!def_sym) {
			for_all_defaults(sym, def_prop) {
				if (E_CALC(def_prop->visible) == no)
					continue;
				sym_calc_visibility(def_prop->def);
				if (def_prop->def->visible != no) {
					def_sym = def_prop->def;
					break;
				}
			}
		}

		if (!def_sym) {
			prop = sym_get_choice_prop(sym);
			for (e = prop->dep; e; e = e->left.expr) {
				sym_calc_visibility(e->right.sym);
				if (e->right.sym->visible != no) {
					def_sym = e->right.sym;
					break;
				}
			}
		}

		S_VAL(newval) = def_sym;
	}

	if (memcmp(&oldval, &newval, sizeof(newval)))
		sym->flags |= SYMBOL_CHANGED;
	sym->curr = newval;

	if (sym_is_choice(sym)) {
		int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
		prop = sym_get_choice_prop(sym);
		for (e = prop->dep; e; e = e->left.expr)
			e->right.sym->flags |= flags;
	}
}

void sym_clear_all_valid(void)
{
	struct symbol *sym;
	int i;

	for_all_symbols(i, sym)
		sym->flags &= ~SYMBOL_VALID;
	sym_change_count++;
}

void sym_set_all_changed(void)
{
	struct symbol *sym;
	int i;

	for_all_symbols(i, sym)
		sym->flags |= SYMBOL_CHANGED;
}

bool sym_tristate_within_range(struct symbol *sym, tristate val)
{
	int type = sym_get_type(sym);

	if (sym->visible == no)
		return false;

	if (type != S_BOOLEAN && type != S_TRISTATE)
		return false;

	switch (val) {
	case no:
		if (sym_is_choice_value(sym) && sym->visible == yes)
			return false;
		return sym_is_optional(sym);
	case mod:
		if (sym_is_choice_value(sym) && sym->visible == yes)
			return false;
		return type == S_TRISTATE;
	case yes:
		return type == S_BOOLEAN || sym->visible == yes;
	}
	return false;
}

bool sym_set_tristate_value(struct symbol *sym, tristate val)
{
	tristate oldval = sym_get_tristate_value(sym);

	if (oldval != val && !sym_tristate_within_range(sym, val))
		return false;

	if (sym->flags & SYMBOL_NEW) {
		sym->flags &= ~SYMBOL_NEW;
		sym->flags |= SYMBOL_CHANGED;
	}
	if (sym_is_choice_value(sym) && val == yes) {
		struct property *prop = sym_get_choice_prop(sym);

		S_VAL(prop->def->def) = sym;
		prop->def->flags &= ~SYMBOL_NEW;
	}

	S_TRI(sym->def) = val;
	if (oldval != val) {
		sym_clear_all_valid();
		if (sym == modules_sym)
			sym_set_all_changed();
	}

	return true;
}

tristate sym_toggle_tristate_value(struct symbol *sym)
{
	tristate oldval, newval;

	oldval = newval = sym_get_tristate_value(sym);
	do {
		switch (newval) {
		case no:
			newval = mod;
			break;
		case mod:
			newval = yes;
			break;
		case yes:
			newval = no;
			break;
		}
		if (sym_set_tristate_value(sym, newval))
			break;
	} while (oldval != newval);
	return newval;
}

bool sym_string_valid(struct symbol *sym, const char *str)
{
	char ch;

	switch (sym->type) {
	case S_STRING:
		return true;
	case S_INT:
		ch = *str++;
		if (ch == '-')
			ch = *str++;
		if (!isdigit((int)ch))
			return false;
		if (ch == '0' && *str != 0)
			return false;
		while ((ch = *str++)) {
			if (!isdigit((int)ch))
				return false;
		}
		return true;
	case S_HEX:
		if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
			str += 2;
		ch = *str++;
		do {
			if (!isxdigit((int)ch))
				return false;
		} while ((ch = *str++));
		return true;
	case S_BOOLEAN:
	case S_TRISTATE:
		switch (str[0]) {
		case 'y':
		case 'Y':
			return sym_tristate_within_range(sym, yes);
		case 'm':
		case 'M':
			return sym_tristate_within_range(sym, mod);
		case 'n':
		case 'N':
			return sym_tristate_within_range(sym, no);
		}
		return false;
	default:
		return false;
	}
}

bool sym_set_string_value(struct symbol *sym, const char *newval)
{
	const char *oldval;
	char *val;
	int size;

	switch (sym->type) {
	case S_BOOLEAN:
	case S_TRISTATE:
		switch (newval[0]) {
		case 'y':
		case 'Y':
			return sym_set_tristate_value(sym, yes);
		case 'm':
		case 'M':
			return sym_set_tristate_value(sym, mod);
		case 'n':
		case 'N':
			return sym_set_tristate_value(sym, no);
		}
		return false;
	default:
		;
	}

	if (!sym_string_valid(sym, newval))
		return false;

	if (sym->flags & SYMBOL_NEW) {
		sym->flags &= ~SYMBOL_NEW;
		sym->flags |= SYMBOL_CHANGED;
	}

	oldval = S_VAL(sym->def);
	size = strlen(newval) + 1;
	if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
		size += 2;
		S_VAL(sym->def) = val = malloc(size);
		*val++ = '0';
		*val++ = 'x';
	} else if (!oldval || strcmp(oldval, newval))
		S_VAL(sym->def) = val = malloc(size);
	else
		return true;

	strcpy(val, newval);
	free((void *)oldval);
	sym_clear_all_valid();

	return true;
}

const char *sym_get_string_value(struct symbol *sym)
{
	tristate val;

	switch (sym->type) {
	case S_BOOLEAN:
	case S_TRISTATE:
		val = sym_get_tristate_value(sym);
		switch (val) {
		case no:
			return "n";
		case mod:
			return "m";
		case yes:
			return "y";
		}
		break;
	default:
		;
	}
	return (const char *)S_VAL(sym->curr);
}

bool sym_is_changable(struct symbol *sym)
{
	if (sym->visible == no)
		return false;
	/* at least 'n' and 'y'/'m' is selectable */
	if (sym_is_optional(sym))
		return true;
	/* no 'n', so 'y' and 'm' must be selectable */
	if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes)
		return true;
	return false;
}

struct symbol *sym_lookup(const char *name, int isconst)
{
	struct symbol *symbol;
	const char *ptr;
	char *new_name;
	int hash = 0;

	//printf("lookup: %s -> ", name);
	if (name) {
		if (name[0] && !name[1]) {
			switch (name[0]) {
			case 'y': return &symbol_yes;
			case 'm': return &symbol_mod;
			case 'n': return &symbol_no;
			}
		}
		for (ptr = name; *ptr; ptr++)
			hash += *ptr;
		hash &= 0xff;

		for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
			if (!strcmp(symbol->name, name)) {
				if ((isconst && symbol->flags & SYMBOL_CONST) ||
				    (!isconst && !(symbol->flags & SYMBOL_CONST))) {
					//printf("h:%p\n", symbol);
					return symbol;
				}
			}
		}
		new_name = strdup(name);
	} else {
		new_name = NULL;
		hash = 256;
	}

	symbol = malloc(sizeof(*symbol));
	memset(symbol, 0, sizeof(*symbol));
	symbol->name = new_name;
	symbol->type = S_UNKNOWN;
	symbol->flags = SYMBOL_NEW;
	if (isconst)
		symbol->flags |= SYMBOL_CONST;

	symbol->next = symbol_hash[hash];
	symbol_hash[hash] = symbol;

	//printf("n:%p\n", symbol);
	return symbol;
}

struct symbol *sym_find(const char *name)
{
	struct symbol *symbol = NULL;
	const char *ptr;
	int hash = 0;

	if (!name)
		return NULL;

	if (name[0] && !name[1]) {
		switch (name[0]) {
		case 'y': return &symbol_yes;
		case 'm': return &symbol_mod;
		case 'n': return &symbol_no;
		}
	}
	for (ptr = name; *ptr; ptr++)
		hash += *ptr;
	hash &= 0xff;

	for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
		if (!strcmp(symbol->name, name) &&
		    !(symbol->flags & SYMBOL_CONST))
				break;
	}

	return symbol;
}

const char *prop_get_type_name(enum prop_type type)
{
	switch (type) {
	case P_PROMPT:
		return "prompt";
	case P_COMMENT:
		return "comment";
	case P_MENU:
		return "menu";
	case P_ROOTMENU:
		return "rootmenu";
	case P_DEFAULT:
		return "default";
	case P_CHOICE:
		return "choice";
	default:
		return "unknown";
	}
}
