#include "asn1fix_internal.h"

static int asn1f_parametrize(arg_t *arg, asn1p_expr_t *ex, asn1p_expr_t *ptype);
static int asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
static int asn1f_param_process_constraints(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);

static asn1p_expr_t *_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
static int _process_constraints(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_t *ptype, asn1p_expr_t *actargs);

int
asn1f_fix_parametrized_assignment(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *ptype;

	assert(expr->expr_type == A1TC_PARAMETRIZED);
	assert(expr->reference);

	DEBUG("(\"%s\" ::= \"%s\" { %s }) for line %d",
		expr->Identifier,
		asn1f_printable_reference(expr->reference),
		asn1f_printable_value(expr->value),
		expr->_lineno);

	/*
	 * Find the corresponding parametrized type definition.
	 */
	DEBUG("Looking for parametrized type definition \"%s\"",
		asn1f_printable_reference(expr->reference));
	ptype = asn1f_lookup_symbol(arg, expr->module, expr->reference);
	if(ptype == NULL) {
		DEBUG("%s: missing parametrized type declaration",
			asn1f_printable_reference(expr->reference));
		return -1;
	}

	/*
	 * Check that the number of arguments which are expected by
	 * the parametrized type declaration is consistent with the
	 * number of arguments supplied by the parametrized assignment.
	 */
	if(asn1f_count_children(expr) != ptype->params->params_count) {
		FATAL("Number of actual arguments %d in %s at line %d "
			"is not equal to number of expected arguments "
			"%d in %s at line %d",
			asn1f_count_children(expr),
			asn1f_printable_reference(expr->reference),
			expr->_lineno,
			ptype->params->params_count,
			ptype->Identifier,
			ptype->_lineno
		);
		return -1;
	}

	/*
	 * Perform an expansion of a parametrized assignment.
	 */
	return asn1f_parametrize(arg, expr, ptype);
}

#define	SUBSTITUTE(to, from)	do {				\
		asn1p_expr_t tmp, *__v;				\
		if((to)->tag.tag_class				\
		&& (from)->tag.tag_class) {			\
			FATAL("Layered tagging "		\
			"in parametrization "			\
			"is not yet supported, "		\
			"contact asn1c author for");		\
			return -1;				\
		}						\
		tmp = *(to);					\
		*(to) = *(from);				\
		TQ_MOVE(&(to)->members, &(from)->members);	\
		*(from) = tmp;					\
		(to)->next = tmp.next;				\
		(to)->parent_expr = tmp.parent_expr;		\
		if(tmp.tag.tag_class)				\
			(to)->tag = tmp.tag;			\
		memset(&((from)->next), 0,			\
			sizeof((from)->next));			\
		memset(&((from)->members), 0,			\
			sizeof((from)->members));		\
		asn1p_expr_free(from);				\
		TQ_FOR(__v, &((to)->members), next) {		\
			assert(__v->parent_expr == (from));	\
			__v->parent_expr = (to);		\
		}						\
	} while(0)

static int
asn1f_parametrize(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype) {
	asn1p_expr_t *nex;
	void *p;
	int ret;

	DEBUG("asn1f_parametrize(%s <= %s)",
		expr->Identifier, ptype->Identifier);

	/*
	 * The algorithm goes like that:
	 * 1. Replace the expression's type with parametrized type.
	 * 2. For every child in the parametrized type, import it
	 * as a child of the expression, replacing all occurences of
	 * symbols which are defined as parametrized type arguments
	 * with the actual values.
	 * 3. Don't forget to parametrize the subtype constraints.
	 */

	nex = asn1p_expr_clone(ptype, 0);
	if(nex == NULL) return -1;

	/*
	 * Cleanup the new expression so there is no ptype-related
	 * stuff hanging around.
	 */
	p = strdup(expr->Identifier);
	if(p) {
		free(nex->Identifier);
		nex->Identifier = p;
	} else {
		asn1p_expr_free(nex);
		return -1;
	}
	asn1p_paramlist_free(nex->params);
	nex->params = NULL;
	nex->meta_type = expr->meta_type;

	ret = asn1f_param_process_recursive(arg, nex, ptype, expr);
	if(ret != 0) {
		asn1p_expr_free(nex);
		return ret;
	}

	SUBSTITUTE(expr, nex);

	return ret;
}

static int
asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
	asn1p_expr_t *child;


	TQ_FOR(child, &(expr->members), next) {
		asn1p_expr_t *ra;
		asn1p_expr_t *ne;	/* new expression (clone) */

		if(asn1f_param_process_constraints(arg, child, ptype, actargs))
			return -1;

		ra = _referenced_argument(child->reference, ptype, actargs);
		if(ra) {
			DEBUG("Substituting parameter for %s %s at line %d",
				child->Identifier,
				asn1f_printable_reference(child->reference),
				child->_lineno
			);
	
			assert(child->meta_type == AMT_TYPEREF);
			assert(child->expr_type == A1TC_REFERENCE);
	
			ne = asn1p_expr_clone(ra, 0);
			if(ne == NULL) return -1;
			assert(ne->Identifier == 0);
			ne->Identifier = strdup(child->Identifier);
			if(ne->Identifier == 0) {
				asn1p_expr_free(ne);
				return -1;
			}
			SUBSTITUTE(child, ne);
		}
	}

	return 0;
}

/*
 * Check that the given ref looks like an argument of a parametrized type.
 */
static asn1p_expr_t *
_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
	asn1p_expr_t *aa;
	int i;

	if(ref == NULL || ref->comp_count != 1)
		return NULL;

	aa = TQ_FIRST(&(actargs->members));
	for(i = 0; i < ptype->params->params_count;
				i++, aa = TQ_NEXT(aa, next)) {
		if(strcmp(ref->components[0].name,
			ptype->params->params[i].argument) == 0)
			return aa;
	}

	return NULL;
}

/*
 * Search for parameters inside constraints.
 */
static int
asn1f_param_process_constraints(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
	asn1p_constraint_t *cts;
	int ret;

	if(!expr->constraints) return 0;

	cts = asn1p_constraint_clone(expr->constraints);
	assert(cts);

	ret = _process_constraints(arg, cts, ptype, actargs);
	if(ret == 1) {
		asn1p_constraint_free(expr->constraints);
		expr->constraints = cts;
		ret = 0;
	} else {
		asn1p_constraint_free(cts);
	}

	return ret;
}

static int
_process_constraints(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
	asn1p_value_t *values[3];
	int rvalue = 0;
	size_t i;

	values[0] = ct->value;
	values[1] = ct->range_start;
	values[2] = ct->range_stop;

	for(i = 0; i < sizeof(values)/sizeof(values[0]); i++) {
		asn1p_value_t *v = values[i];
		asn1p_expr_t *ra;
		asn1p_ref_t *ref;
		char *str;

		if(!v || v->type != ATV_REFERENCED) continue;

		ref = v->value.reference;
		ra = _referenced_argument(ref, ptype, actargs);
		if(!ra) continue;

		DEBUG("_process_constraints(%s), ra=%s",
			asn1f_printable_reference(ref), ra->Identifier);

		if(ra->expr_type == A1TC_PARAMETRIZED) {
			DEBUG("Double %s", "parametrization");
		}

		assert(ra->Identifier);
		str = strdup(ra->Identifier);
		if(!str) return -1;

		assert(ref->comp_count == 1);
		ref = asn1p_ref_new(ref->_lineno);
		if(!ref) { free(str); return -1; }

		if(asn1p_ref_add_component(ref, str, 0)) {
			free(str);
			return -1;
		}

		asn1p_ref_free(v->value.reference);
		v->value.reference = ref;
		rvalue = 1;
	}

	/* Process the rest of constraints recursively */
	for(i = 0; i < ct->el_count; i++) {
		int ret = _process_constraints(arg, ct->elements[i],
			ptype, actargs);
		if(ret == -1)
			rvalue = -1;
		else if(ret == 1 && rvalue != -1)
			rvalue = 1;
	}

	return rvalue;
}

