#include "asn1fix_internal.h"

static int _asn1f_copy_value(arg_t *arg, asn1p_expr_t *to,asn1p_expr_t *from);

int
asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) {
	asn1p_expr_t *val_type_expr;
	asn1p_expr_t *value_expr;
	asn1p_expr_t *type_expr;
	int ret;

	/* Make sure this IS a value assignment */
	assert(expr->meta_type == AMT_VALUE);
	assert(expr->value);

	DEBUG("%s(=\"%s\", %x)", __func__,
		asn1f_printable_value(expr->value), expr->expr_type);

	/*
	 * 1. Find the terminal type for this assignment.
	 */
	type_expr = asn1f_find_terminal_type(arg, expr);
	DEBUG("%s(): terminal type %p", __func__, type_expr);
	if(type_expr == 0) {
		FATAL("Terminal type for is %s not found", expr->Identifier);
		return -1;
	}

	if(asn1f_look_value_in_type(arg, type_expr, expr) == -1)
		return -1;

	/*
	 * 2. Find the terminal value also.
	 */
	value_expr = asn1f_find_terminal_value(arg, expr);
	if(value_expr) {
		DEBUG("\tTerminal value for %s->%s is %s at line %d",
			expr->Identifier, asn1f_printable_value(expr->value),
			value_expr->Identifier, value_expr->_lineno);
	} else {
		DEBUG("\tTerminal value for %s->%s not found",
			expr->Identifier, asn1f_printable_value(expr->value));
		return -1;
	}

	/*
	 * 3. Find the _type_ of a _terminal value_.
	 */
	WITH_MODULE(value_expr->module,
		val_type_expr = asn1f_find_terminal_type(arg, value_expr));
	if(val_type_expr) {
		DEBUG("\tTerminal type of value %s->%s is %s at line %d",
			expr->Identifier, asn1f_printable_value(expr->value),
			val_type_expr->Identifier, val_type_expr->_lineno);
	} else {
		DEBUG("\tTerminal type of value %s->%s not found",
			expr->Identifier, asn1f_printable_value(expr->value));
		return -1;
	}

	/*
	 * 4. Check compatibility between the type of the current expression
	 * and the type of the discovered value.
	 */
	ret = asn1f_check_type_compatibility(arg, type_expr, val_type_expr);
	if(ret == -1) {
		switch(type_expr->expr_type) {
		case ASN_BASIC_INTEGER:
		case ASN_BASIC_ENUMERATED:
			FATAL("Incompatible type of %s at %d with %s at %d",
			type_expr->Identifier, type_expr->_lineno,
			val_type_expr->Identifier, val_type_expr->_lineno);
			return -1;
		case ASN_BASIC_OBJECT_IDENTIFIER:
			/*
			 * Ignore this for now.
			 * We can't deal with OIDs inheritance properly yet.
			 */
			return 0;
		default:
			break;
		}
		WARNING("\tIncompatible type of %s at %d with %s at %d",
			type_expr->Identifier, type_expr->_lineno,
			val_type_expr->Identifier, val_type_expr->_lineno);
		return 1;
	}

	if(asn1f_look_value_in_type(arg, val_type_expr, expr) == -1)
		return -1;

	/*
	 * 5. Copy value from the terminal value into the current expression.
	 */
	ret = _asn1f_copy_value(arg, expr, value_expr);
	if(ret == -1) {
		DEBUG("\tValue %s cannot be copied from line %d to line %d",
			asn1f_printable_value(value_expr->value),
			value_expr->_lineno, expr->_lineno);
		return -1;
	}

	DEBUG("\tFinal value for \"%s\" at line %d is %s",
		expr->Identifier, expr->_lineno,
		asn1f_printable_value(expr->value));

	return 0;
}

static int
_asn1f_copy_value(arg_t *arg, asn1p_expr_t *to, asn1p_expr_t *from) {
	asn1p_value_t *v;

	v = asn1p_value_clone(from->value);
	if(v) {
		asn1p_value_free(to->value);
		to->value = v;
		DEBUG("Copied value %s from \"%s\" on line %d "
			"to \"%s\" on line %d",
			asn1f_printable_value(v),
			from->Identifier,
			from->_lineno,
			to->Identifier,
			to->_lineno
		);
		return 0;
	} else {
		return -1;
	}
}

int
asn1f_look_value_in_type(arg_t *arg,
		asn1p_expr_t *type_expr,
		asn1p_expr_t *value_expr) {
	asn1p_expr_t *child_expr;
	char *identifier;

	if(value_expr->value->type != ATV_REFERENCED
	|| value_expr->value->value.reference->comp_count != 1)
		return 0;
	if(type_expr->expr_type != ASN_BASIC_INTEGER
	&& type_expr->expr_type != ASN_BASIC_ENUMERATED)
		return 0;

	DEBUG("%s(for %s in %s %x) for line %d", __func__,
		asn1f_printable_value(value_expr->value),
		type_expr->Identifier,
		type_expr->expr_type,
		value_expr->_lineno);

	/*
	 * Look into the definitions of the type itself:
	 * Type1 ::= INTEGER { a(1), b(2) }
	 * value Type1 = b	-- will assign 2
	 */
	identifier = value_expr->value->value.reference->components[0].name;

	child_expr = asn1f_lookup_child(type_expr, identifier);
	DEBUG("\tLooking into a type %s at line %d for %s at line %d: %s",
		type_expr->Identifier, type_expr->_lineno,
		identifier, value_expr->_lineno,
		child_expr
			? asn1f_printable_value(child_expr->value)
			: "<not found>"
		);

	if(child_expr && child_expr->value) {
		if(_asn1f_copy_value(arg, value_expr, child_expr))
			return -1;
		/* Fall through */
	}

	return 0;
}
