#include "asn1fix_internal.h"

enum ftt_what {
	FTT_TYPE,	/* Find the type of the given expression */
	FTT_VALUE,	/* Find the value of the given expression */
};

static asn1p_expr_t *asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what);
static int asn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name);


/*
 * Lookup a child by its name.
 */
asn1p_expr_t *
asn1f_lookup_child(asn1p_expr_t *tc, const char *name) {
	asn1p_expr_t *child_tc;

	TQ_FOR(child_tc, &(tc->members), next) {
		if(child_tc->Identifier
		&& strcmp(child_tc->Identifier, name) == 0) {
			return child_tc;
		}
	}

	errno = ESRCH;
	return NULL;
}

asn1p_module_t *
asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const char *name) {
	asn1p_xports_t *xp;
	asn1p_expr_t *tc;

	/*
	 * Search in which exactly module this name is defined.
	 */
	TQ_FOR(xp, &(mod->imports), xp_next) {
		TQ_FOR(tc, &(xp->members), next) {
			if(strcmp(name, tc->Identifier) == 0)
				break;
		}
		if(tc) break;
	}
	if(xp == NULL) {
		errno = ESRCH;
		return NULL;
	}

	/*
	 * Okay, right now we have a module name and, hopefully, an OID.
	 * Search the arg->asn for the specified module.
	 */
	mod = asn1f_lookup_module(arg, xp->fromModuleName, xp->identifier.oid);
	if(mod == NULL) {
		/* Conditional debug */
		if(!(arg->expr->_mark & TM_BROKEN)) {
			arg->expr->_mark |= TM_BROKEN;
			FATAL("Cannot find external module \"%s\" "
				"mentioned for "
				"\"%s\" at line %d. "
				"Obtain this module and instruct compiler to process it too.",
				xp->fromModuleName, name, arg->expr->_lineno);
		}
		/* ENOENT/ETOOMANYREFS */
		return NULL;
	}

	/*
	 * Check that the EXPORTS section of this module contains
	 * the symbol we care about, or it is EXPORTS ALL.
	 */
	if(asn1f_compatible_with_exports(arg, mod, name)) {
		errno = EPERM;
		return NULL;
	}

	return mod;
}

asn1p_module_t *
asn1f_lookup_module(arg_t *arg, const char *module_name, asn1p_oid_t *oid) {
	asn1p_module_t *mod;

	assert(module_name);

	/*
	 * If OID is given, the module_name is unused.
	 * If OID is not given, the module_name may mean
	 * either the real module's name, or the symbol which is the
	 * result of renaming. Check this first.
	 */
	if(oid == 0) {
		asn1p_xports_t *xp;
		/*
		 * Check inside the IMPORTS section for possible renaming.
		 * Renaming practically means that a module_name is mentioned
		 * somewhere in the IMPORTS section AND OID is given.
		 */
		TQ_FOR(xp, &(arg->mod->imports), xp_next) {
			if(strcmp(module_name, xp->fromModuleName))
				continue;
			if(oid) {
				FATAL("Ambiguous reference: "
					"%s "
					"matches several modules",
					module_name);
				errno = ETOOMANYREFS;
				return NULL;
			}
			/*
			 * Yes, there is a renaming.
			 * Make lookup use OID instead.
			 */
			oid = xp->identifier.oid;
		}
	}

	/*
	 * Perform lookup using OID or module_name.
	 */
	TQ_FOR(mod, &(arg->asn->modules), mod_next) {
		if(oid) {
			if(mod->module_oid) {
				if(asn1p_oid_compare(oid,
					mod->module_oid)) {
					continue;
				} else {
					/* Match! Even if name doesn't. */
					return mod;
				}
			} else {
				/* Not match, even if name is the same. */
				continue;
			}
		}
	
		if(strcmp(module_name, mod->ModuleName) == 0)
			return mod;
	}

	DEBUG("\tModule \"%s\" not found", module_name);

	errno = ENOENT;
	return NULL;
}

static asn1p_expr_t *
asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, asn1p_ref_t *ref, int recursion_depth) {
	asn1p_expr_t *ref_tc;			/* Referenced tc */
	asn1p_module_t *imports_from;
	char *modulename;
	char *identifier;

	/*
	 * First of all, a reference to a symbol may be specified
	 * using several possible forms:
	 * a) simple identifier
	 *	v INTEGER ::= value
	 * b) external reference
	 * 	v INTEGER ::= Module1.value
	 * c) class-related stuff (the most complex stuff)
	 * 	v ::= <[A-Z][A-Z0-9a-z-]*>.&<[A-Z0-9a-z-]+>.
	 * All other forms are not implemented at this moment.
	 */

	DEBUG("(%s) in %s for line %d",
		asn1f_printable_reference(ref),
		mod->ModuleName,
		ref->_lineno);

	if(recursion_depth++ > 30 /* Arbitrary constant */) {
		FATAL("Excessive circular referencing detected in module %s for %s at line %d",
			mod->ModuleName,
			asn1f_printable_reference(ref),
			ref->_lineno);
		errno = ETOOMANYREFS;
		return NULL;
	}

	if(ref->comp_count == 1) {
		modulename = NULL;
		identifier = ref->components[0].name;
	} else if(ref->comp_count == 2
		&& ref->components[1].name[0] != '&') {
		modulename = ref->components[0].name;
		identifier = ref->components[1].name;
	} else if(ref->comp_count > 1
		&& isupper(ref->components[0].name[0])
		&& ref->components[1].name[0] == '&') {
		asn1p_expr_t *extract;
		/*
		 * This is a reference to a CLASS-related stuff.
		 * Employ a separate function for that.
		 */
		extract = asn1f_class_access(arg, mod, rhs_pspecs, ref);
		
		return extract;
	} else {
		DEBUG("\tToo many components: %d", ref->comp_count);
		errno = EINVAL;
		return NULL;
	}

	/*
	 * If module name is specified explicitly
	 * OR the current module's IMPORTS clause contains the identifier,
	 * fetch that module.
	 */
	if(modulename) {
		imports_from = asn1f_lookup_module(arg, modulename, 0);
		if(imports_from == NULL) {
			FATAL("Module \"%s\" "
				"mentioned at line %d is not found",
				modulename, ref->_lineno);
			return NULL;
		}

		/*
		 * Check that the EXPORTS section of this module contains
		 * the symbol we care about, or it is EXPORTS ALL.
		 */
		if(asn1f_compatible_with_exports(arg,imports_from,identifier)) {
			errno = EPERM;
			return NULL;
		}
	} else {
		/* Search inside the IMPORTS section of the current module */
		imports_from = asn1f_lookup_in_imports(arg, mod, identifier);
		if(imports_from == NULL && errno != ESRCH) {
			/*
			 * Return only of the name was not found.
			 * If module was not found or more serious error
			 * encountered, just return preserving the errno.
			 */
			return NULL;
		}
	}

	/*
	 * The symbol is being imported from another module.
	 */
  importing:
	if(imports_from) {
		asn1p_ref_t tmpref = *ref;
		asn1p_expr_t *expr;
		if(modulename) {
			/*
			 * The modulename is specified inside this reference.
			 * To avoid recursion, reformat the reference
			 * as it were local to that module.
			 */
			tmpref.components++;	/* Hide the first element */
			tmpref.comp_count--;
			assert(tmpref.comp_count > 0);
		}

		expr = asn1f_lookup_symbol_impl(arg, imports_from,
				rhs_pspecs, &tmpref, recursion_depth);
		if(!expr && !(arg->expr->_mark & TM_BROKEN)
		&& !(imports_from->_tags & MT_STANDARD_MODULE)) {
			arg->expr->_mark |= TM_BROKEN;
			if(modulename) {
				FATAL("Module %s referred by %s in module %s "
					"does not contain the requested symbol",
				imports_from->ModuleName,
				asn1f_printable_reference(ref),
				mod->ModuleName);
			} else {
				FATAL("Module %s referred in IMPORTS section "
				"for %s of module %s does not contain "
				"the requested symbol",
				imports_from->ModuleName,
				asn1f_printable_reference(ref),
				mod->ModuleName);
			}
		}
		return expr;
	}

	/*
	 * Now we know where to search for a value: in the current module.
	 */
	TQ_FOR(ref_tc, &(mod->members), next) {
		if(ref_tc->Identifier)
		if(strcmp(ref_tc->Identifier, identifier) == 0)
			break;
	}
	if(ref_tc) {
		/* It is acceptable that we don't use input parameters */
		if(rhs_pspecs && !ref_tc->lhs_params) {
			WARNING("Parameterized type %s expected "
				"for %s at line %d",
				ref_tc->Identifier,
				asn1f_printable_reference(ref),
				ref->_lineno);
		}
		if(!rhs_pspecs && ref_tc->lhs_params) {
			FATAL("Type %s expects specialization "
				"from %s at line %d",
				ref_tc->Identifier,
				asn1f_printable_reference(ref),
				ref->_lineno);
			errno = EPERM;
			return NULL;
		}
		if(rhs_pspecs && ref_tc->lhs_params) {
			/* Specialize the target */
			ref_tc = asn1f_parameterization_fork(arg,
				ref_tc, rhs_pspecs);
		}

		return ref_tc;
	}

	/*
	 * Not found in the current module.
	 * Search in our default standard module.
	 */
	{
		/* Search inside standard module */
		asn1p_oid_t *uioc_oid;
		asn1p_oid_arc_t arcs[] = {
			{ 1, "iso" },
			{ 3, "org" },
			{ 6, "dod" },
			{ 1, "internet" },
			{ 4, "private" },
			{ 1, "enterprise" },
			{ 9363, "spelio" },
			{ 1, "software" },
			{ 5, "asn1c" },
			{ 3, "standard-modules" },
			{ 0, "auto-imported" },
			{ 1, 0 }
		};

		if(!imports_from) {
			uioc_oid = asn1p_oid_construct(arcs,
				sizeof(arcs)/sizeof(arcs[0]));

			if(!mod->module_oid
				|| asn1p_oid_compare(mod->module_oid, uioc_oid))
				imports_from = asn1f_lookup_module(arg,
					"ASN1C-UsefulInformationObjectClasses",
					uioc_oid);

			asn1p_oid_free(uioc_oid);
			if(imports_from) goto importing;
		}
	}

	DEBUG("Module \"%s\" does not contain \"%s\" "
		"mentioned at line %d: %s",
		mod->ModuleName,
		identifier,
		ref->_lineno,
		strerror(errno));

	if(asn1f_check_known_external_type(identifier) == 0) {
		errno = EEXIST; /* Exists somewhere */
	} else {
		errno = ESRCH;
	}
	return NULL;
}


asn1p_expr_t *
asn1f_lookup_symbol(arg_t *arg,
	asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, asn1p_ref_t *ref) {
	return asn1f_lookup_symbol_impl(arg, mod, rhs_pspecs, ref, 0);
}

asn1p_expr_t *
asn1f_find_terminal_type(arg_t *arg, asn1p_expr_t *expr) {
	return asn1f_find_terminal_thing(arg, expr, FTT_TYPE);
}

asn1p_expr_t *
asn1f_find_terminal_value(arg_t *arg, asn1p_expr_t *expr) {
	return asn1f_find_terminal_thing(arg, expr, FTT_VALUE);
}

static asn1p_expr_t *
asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
	asn1p_ref_t *ref = 0;
	asn1p_expr_t *tc;

	switch(what) {
	case FTT_TYPE:
		/* Expression may be a terminal type itself */
		if(expr->expr_type != A1TC_REFERENCE)
			return expr;
		ref = expr->reference;
		break;
	case FTT_VALUE:
		assert(expr->meta_type == AMT_VALUE);
		assert(expr->value);
		/* Expression may be a terminal type itself */
		if(expr->value->type != ATV_REFERENCED)
			return expr;
		ref = expr->value->value.reference;
		break;
	}

	DEBUG("%s(%s->%s) for line %d",
		(what == FTT_VALUE)?"VALUE":"TYPE",
		expr->Identifier, asn1f_printable_reference(ref),
		expr->_lineno);

	assert(ref);

	/*
	 * Lookup inside the type itself (ENUMERATED, INTEGER, etc).
	 */
	if(what == FTT_VALUE) {
		asn1p_expr_t *val_type_tc;
		val_type_tc = asn1f_find_terminal_type(arg, expr);
		if(val_type_tc
		&& asn1f_look_value_in_type(arg, val_type_tc, expr))
			return NULL;
		if(expr->value->type != ATV_REFERENCED) {
			return expr;
		}
		assert(ref == expr->value->value.reference);
		ref = expr->value->value.reference;
	}

	/*
	 * Lookup inside the default module and its IMPORTS section.
	 */
	tc = asn1f_lookup_symbol(arg, expr->module, expr->rhs_pspecs, ref);
	if(tc == NULL) {
		/*
	 	 * Lookup inside the ref's module and its IMPORTS section.
	 	 */
		tc = asn1f_lookup_symbol(arg, ref->module, expr->rhs_pspecs, ref);
		if(tc == NULL) {
			DEBUG("\tSymbol \"%s\" not found: %s",
				asn1f_printable_reference(ref),
				strerror(errno));
			return NULL;
		}
	}

	/*
	 * Recursive loops detection.
	 */
	if(tc->_mark & TM_RECURSION) {
		DEBUG("Recursion loop detected for %s at line %d",
			asn1f_printable_reference(ref), ref->_lineno);
		errno = EPERM;
		return NULL;
	}

	tc->_type_referenced = 1;
	tc->_mark |= TM_RECURSION;
	WITH_MODULE(tc->module,
		expr = asn1f_find_terminal_thing(arg, tc, what));
	tc->_mark &= ~TM_RECURSION;

	return expr;
}

/*
 * Make sure that the specified name is present or otherwise does
 * not contradict with the EXPORTS clause of the specified module.
 */
static int
asn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name) {
	asn1p_xports_t *exports;
	asn1p_expr_t *item;

	assert(mod);
	assert(name);

	exports = TQ_FIRST(&(mod->exports));
	if(exports == NULL) {
		/* No EXPORTS section or EXPORTS ALL; */
		return 0;
	}

	TQ_FOR(item, &(exports->members), next) {
		if(strcmp(item->Identifier, name) == 0)
			return 0;
	}

	/* Conditional debug */
	if(!(arg->expr->_mark & TM_BROKEN)) {
		arg->expr->_mark |= TM_BROKEN;
		FATAL("EXPORTS section of module %s in %s "
			"does not mention %s at line %d",
			mod->ModuleName, mod->source_file_name, name,
			arg->expr->_lineno);
	}

	errno = ESRCH;
	return -1;
}
