#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_expr_t *expr;

	expr = calloc(1, sizeof *expr);
	if(expr) {
		TQ_INIT(&(expr->members));
		expr->spec_index = -1;
		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);
			return clone;
		} else if(errno != ESRCH) {
			return NULL;	/* Hard error */
		}
	}
	if(!clone) clone = asn1p_expr_new(expr->_lineno);
	if(!clone) return NULL;

	/*
	 * Copy simple fields.
	 */
	CLCOPY(meta_type);
	CLCOPY(expr_type);
	CLCOPY(tag);
	CLCOPY(marker.flags);		/* OPTIONAL/DEFAULT */
	CLCOPY(module);
	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);
	CLCLONE(marker.default_value, asn1p_value_clone);
	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);
	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->value) {
		fprintf(stderr,
		"FATAL: Parameterization did not resolve value reference "
		"at line %d", ref->_lineno);
		asn1p_expr_free(target);
		errno = EPERM;
		return NULL;
	}

	cval = asn1p_value_clone(target->value);
	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;
}


/*
 * 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);
		}

		if(expr->Identifier)
			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;
}
