#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 assistance "		\
		"with line %d", (to)->_lineno);			\
		return -1;					\
	}							\
	/* This code shall not be invoked too early */		\
	assert((to)->combined_constraints == NULL);		\
	assert((from)->combined_constraints == NULL);		\
	/* Copy stuff, and merge some parameters */		\
	tmp = *(to);						\
	*(to) = *(from);					\
	TQ_MOVE(&(to)->members, &(from)->members);		\
	*(from) = tmp;						\
	(to)->next = tmp.next;					\
	(to)->parent_expr = tmp.parent_expr;			\
	assert((to)->marker.flags == EM_NOMARK);		\
	(to)->marker = tmp.marker;				\
	if(tmp.tag.tag_class)					\
		(to)->tag = tmp.tag;				\
	if(tmp.constraints) {					\
		if((to)->constraints) {				\
			asn1p_constraint_t *ct;			\
			ct = asn1p_constraint_new(		\
				(to)->constraints->_lineno);	\
			ct->type = ACT_CA_SET;			\
			asn1p_constraint_insert(ct,		\
				(to)->constraints);		\
			asn1p_constraint_insert(ct,		\
				tmp.constraints);		\
			(to)->constraints = ct;			\
		} else {					\
			(to)->constraints = tmp.constraints;	\
		}						\
	}							\
	(from)->constraints = 0;				\
	(from)->marker.default_value = 0;			\
	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.
	 */
	if(expr->Identifier) {
		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;
}

