#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>

#include "asn1parser.h"

static asn1p_expr_t *asn1p_expr_clone_impl(asn1p_expr_t *expr, int skip_extensions, asn1p_expr_t *(*)(asn1p_expr_t *, void *), void *);
static asn1p_value_t *value_resolver(asn1p_value_t *, void *arg);

/*
 * Construct a new empty types collection.
 */
asn1p_expr_t *
asn1p_expr_new(int _lineno, asn1p_module_t *mod) {
	asn1p_expr_t *expr;

	expr = calloc(1, sizeof *expr);
	if(expr) {
		TQ_INIT(&(expr->members));
		expr->spec_index = -1;
		expr->module = mod;
		expr->_lineno = _lineno;
	}

	return expr;
}

asn1p_expr_t *
asn1p_expr_clone(asn1p_expr_t *expr, int skip_extensions) {
	return asn1p_expr_clone_impl(expr, skip_extensions, 0, 0);
}

asn1p_expr_t *
asn1p_expr_clone_with_resolver(asn1p_expr_t *expr, asn1p_expr_t *(*r)(asn1p_expr_t *, void *), void *rarg) {
	return asn1p_expr_clone_impl(expr, 0, r, rarg);
}

static asn1p_expr_t *
asn1p_expr_clone_impl(asn1p_expr_t *expr, int skip_extensions, asn1p_expr_t *(*r)(asn1p_expr_t *, void *), void *rarg) {
	asn1p_value_t *(*vr)(asn1p_value_t *, void *) = 0;
	asn1p_expr_t *clone = 0;
	asn1p_expr_t *tcmemb;	/* Child of tc */
	int hit_ext = 0;

#define	CLCOPY(field)	do { clone->field = expr->field; } while(0)
#define	CLCLONE(field, func)	do { if(expr->field) {			\
			clone->field = func(expr->field);		\
			if(clone->field == NULL) {			\
				asn1p_expr_free(clone);			\
				return NULL;				\
			}						\
		} } while(0)
#define	CLVRCLONE(field, func)	do { if(expr->field) {			\
			clone->field = func(expr->field, vr, rarg);	\
			if(clone->field == NULL) {			\
				asn1p_expr_free(clone);			\
				return NULL;				\
			}						\
		} } while(0)

	if(r) {
		vr = value_resolver;
		clone = r(expr, rarg);
		if(clone) {
			/* Merge constraints */
			if(expr->constraints) {
				asn1p_constraint_t *tmpct = asn1p_constraint_clone_with_resolver(expr->constraints, vr, rarg);
				if(clone->constraints) {
					if(asn1p_constraint_insert(clone->constraints, tmpct)) {
						asn1p_constraint_free(tmpct);
						asn1p_expr_free(clone);
						return NULL;
					}
				} else {
					clone->constraints = tmpct;
				}
				assert(expr->combined_constraints == 0);
			}
			/* Merge defaults */
			CLCOPY(marker.flags);
			CLVRCLONE(marker.default_value,
				asn1p_value_clone_with_resolver);
			if(clone->tag.tag_class == TC_NOCLASS) {
				CLCOPY(tag);
			} else if(expr->tag.tag_class != TC_NOCLASS) {
				fprintf(stderr, "asn1c does not support "
					"nested tagging in parameterization, "
					"necessary at line %d\n",
					expr->_lineno);
				asn1p_expr_free(clone);
				return NULL;
			}
			return clone;
		} else if(errno != ESRCH) {
			return NULL;	/* Hard error */
		}
	}
	if(!clone) clone = asn1p_expr_new(expr->_lineno, expr->module);
	if(!clone) return NULL;

	/*
	 * Copy simple fields.
	 */
	CLCOPY(meta_type);
	CLCOPY(expr_type);
	CLCOPY(tag);
	CLCOPY(marker.flags);		/* OPTIONAL/DEFAULT */
	CLCOPY(_mark);

	clone->data = 0;	/* Do not clone this */
	clone->data_free = 0;	/* Do not clone this */

	/*
	 * Clone complex fields.
	 */
	CLCLONE(Identifier, strdup);
	CLCLONE(reference, asn1p_ref_clone);
	CLVRCLONE(constraints, asn1p_constraint_clone_with_resolver);
	CLVRCLONE(combined_constraints, asn1p_constraint_clone_with_resolver);
	CLCLONE(lhs_params, asn1p_paramlist_clone);
	CLVRCLONE(value, asn1p_value_clone_with_resolver);
	CLVRCLONE(marker.default_value, asn1p_value_clone_with_resolver);
	CLCLONE(with_syntax, asn1p_wsyntx_clone);

	/*
	 * Copy all the children of this expr.
	 */
	TQ_FOR(tcmemb, &(expr->members), next) {
		asn1p_expr_t *cmemb;

		if(skip_extensions
		&& tcmemb->expr_type == A1TC_EXTENSIBLE) {
			hit_ext++; /* Even if hit_ext wraps around, we're OK. */
			continue;
		}
		if(hit_ext == 1) continue;	/* Skip between ...'s */

		cmemb = asn1p_expr_clone_impl(tcmemb, skip_extensions, r, rarg);
		if(cmemb == NULL) {
			asn1p_expr_free(clone);
			return NULL;
		}
		asn1p_expr_add(clone, cmemb);
	}

	return clone;
}


static asn1p_value_t *
value_resolver(asn1p_value_t *value, void *rarg) {
	asn1p_value_t *cval;
	asn1p_expr_t *tmpexpr;
	asn1p_expr_t *target;
	asn1p_ref_t *ref;
	struct {
		asn1p_expr_t *(*expr_resolve)(asn1p_expr_t *, void *arg);
	} *varg = rarg;

	if(!value || value->type != ATV_REFERENCED) {
		errno = ESRCH;
		return NULL;
	}

	ref = value->value.reference;
	tmpexpr = asn1p_expr_new(ref->_lineno, 0);
	tmpexpr->meta_type = AMT_TYPEREF;
	tmpexpr->expr_type = A1TC_REFERENCE;
	tmpexpr->reference = ref;
	target = varg->expr_resolve(tmpexpr, rarg);
	tmpexpr->reference = 0;
	asn1p_expr_free(tmpexpr);

	if(!target)
		return NULL;	/* errno's are compatible */

	if(target->meta_type == AMT_VALUE) {
		if(!target->value) {
			fprintf(stderr,
			"FATAL: Parameterization did not resolve "
			"value reference at line %d\n", ref->_lineno);
			asn1p_expr_free(target);
			errno = EPERM;
			return NULL;
		}
		cval = asn1p_value_clone(target->value);
	} else if(target->meta_type == AMT_VALUESET) {
		if(!target->constraints) {
			fprintf(stderr,
			"FATAL: Parameterization did not resolve "
			"value set reference at line %d\n", ref->_lineno);
			asn1p_expr_free(target);
			errno = EPERM;
			return NULL;
		}
		cval = asn1p_value_fromconstr(target->constraints, 1);
	} else {
		errno = EPERM;
		cval = NULL;
	}

	asn1p_expr_free(target);
	return cval;
}

/*
 * Add expression as a member of another.
 */
void
asn1p_expr_add(asn1p_expr_t *to, asn1p_expr_t *what) {
	TQ_ADD(&(to->members), what, next);
	what->parent_expr = to;
}

/*
 * Add inner expressions as members of another.
 */
void
asn1p_expr_add_many(asn1p_expr_t *to, asn1p_expr_t *from_what) {
	asn1p_expr_t *expr;
	TQ_FOR(expr, &(from_what->members), next) {
        expr->parent_expr = to;
    }
	TQ_CONCAT(&(to->members), &(from_what->members), next);
}


/*
 * Destruct the types collection structure.
 */
void
asn1p_expr_free(asn1p_expr_t *expr) {
	if(expr) {
		asn1p_expr_t *tm;

		/* Remove all children */
		while((tm = TQ_REMOVE(&(expr->members), next))) {
			if(tm->parent_expr != expr)
				printf("<%s:%p !-> %s:%p>\n",
					tm->Identifier, tm->parent_expr,
					expr->Identifier, expr);
			assert(tm->parent_expr == expr);
			asn1p_expr_free(tm);
		}

		free(expr->Identifier);
		if(expr->reference)
			asn1p_ref_free(expr->reference);
		if(expr->constraints)
			asn1p_constraint_free(expr->constraints);
		if(expr->combined_constraints)
			asn1p_constraint_free(expr->combined_constraints);
		if(expr->lhs_params)
			asn1p_paramlist_free(expr->lhs_params);
		if(expr->value)
			asn1p_value_free(expr->value);
		if(expr->marker.default_value)
			asn1p_value_free(expr->marker.default_value);
		if(expr->with_syntax)
			asn1p_wsyntx_free(expr->with_syntax);

		if(expr->data && expr->data_free)
			expr->data_free(expr->data);

		memset(expr, 0, sizeof(*expr));
		free(expr);
	}
}


char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *buf) {
	static char buf_stat[TAG2STRING_BUFFER_SIZE];
	char *start;
	char *end;

	if(!buf) buf = buf_stat;
	start = buf;
	end = buf + TAG2STRING_BUFFER_SIZE;

	if(tag->tag_class == TC_NOCLASS) {
		*buf = 0;
		return buf;
	}

	strcpy(buf, "[");
	switch(tag->tag_class) {
	case TC_NOCLASS:
		assert(tag->tag_class != TC_NOCLASS);
		break;
	case TC_UNIVERSAL:	strcat(buf, "UNIVERSAL ");	break;
	case TC_PRIVATE:	strcat(buf, "PRIVATE ");	break;
	case TC_APPLICATION:	strcat(buf, "APPLICATION ");	break;
	case TC_CONTEXT_SPECIFIC:
		break;
	}
	buf += snprintf(buf + strlen(buf), end - buf,
		"%" PRIdASN "]", tag->tag_value);
	assert((unsigned int)(buf - end) > sizeof(" IMPLICIT "));

	switch(tag->tag_mode) {
	case TM_DEFAULT: break;
	case TM_IMPLICIT: strcat(buf, " IMPLICIT"); break;
	case TM_EXPLICIT: strcat(buf, " EXPLICIT"); break;
	}

	return start;
}
