#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 */
	FTT_CONSTR_TYPE /* Find the type of the given expression having constraint */ 
};

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, const 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_expr_t *rhs_pspecs, const asn1p_ref_t *ref, int recursion_depth) {
    asn1_namespace_t *initial_namespace = arg->ns;
	asn1p_ref_t tmp_ref;
	asn1p_module_t *imports_from;
	char *modulename;
	char *identifier;

    if(ref->module && arg->mod != ref->module) {
        return WITH_MODULE(
            ref->module,
            asn1f_lookup_symbol_impl(arg, rhs_pspecs, ref, recursion_depth));
    }

	/*
	 * 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("Lookup (%s) in %s for line %d",
		asn1f_printable_reference(ref),
		asn1_namespace_string(initial_namespace),
		ref->_lineno);

	if(recursion_depth++ > 30 /* Arbitrary constant */) {
        FATAL(
            "Excessive circular referencing detected in namespace %s for %s at "
            "line %d",
            asn1_namespace_string(initial_namespace),
            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, rhs_pspecs, ref);
		
		return extract;
	} else {
		DEBUG("\tToo many components: %d", ref->comp_count);
		errno = EINVAL;
		return NULL;
	}

    if(modulename) {
        /*
         * The modulename is specified inside this reference.
         * To avoid recursion, reformat the reference
         * as it were local to that module.
         */
        tmp_ref = *ref;
        tmp_ref.components++; /* Hide the first element */
        tmp_ref.comp_count--;
        assert(tmp_ref.comp_count > 0);
        ref = &tmp_ref;
    }

    asn1_namespace_t *my_namespace = initial_namespace;

#define DISPOSE_OF_MY_NAMESPACE()               \
    do {                                        \
        int tmp_errno = errno;                  \
        if(my_namespace != initial_namespace) { \
            asn1_namespace_free(my_namespace);  \
            my_namespace = NULL;                \
        }                                       \
        errno = tmp_errno;                      \
    } while(0)

    /*
     * If module name is specified explicitly
     * OR the current module's IMPORTS clause contains the identifier,
     * switch namespace to 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;
        }

        my_namespace = asn1_namespace_new_from_module(imports_from, 1);
        DEBUG("Lookup (%s) in %s for line %d", asn1f_printable_reference(ref),
              asn1_namespace_string(my_namespace), ref->_lineno);
    }

    size_t namespace_switches = 0;

    /*
     * Search through all layers of the namespace.
     */
    for(ssize_t ns_item = my_namespace->elements_count - 1; ns_item >= 0;
        ns_item--) {
        struct asn1_namespace_element_s *ns_el =
            &my_namespace->elements[ns_item];
        asn1p_expr_t *ref_tc; /* Referenced tc */

        switch(ns_el->selector) {
        case NAM_SYMBOL:
            if(modulename) {
                /*
                 * Trying to match a fully specified "Module.Symbol"
                 * against the "Symbol" parameter. Doesn't match.
                 */
                continue;
            }
            if(strcmp(ns_el->u.symbol.identifier, identifier) != 0) {
                continue;
            } else {
                DEBUG("Lookup (%s) in %s for line %d => found as parameter",
                      asn1f_printable_reference(ref),
                      asn1_namespace_string(my_namespace), ref->_lineno);
                DISPOSE_OF_MY_NAMESPACE();
                return ns_el->u.symbol.resolution;
            }
        case NAM_SPACE:
            /*
             * Do a direct symbol search in the given module.
             */
            TQ_FOR(ref_tc, &(ns_el->u.space.module->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);
                }

                DISPOSE_OF_MY_NAMESPACE();
                return ref_tc;
            }

    /*
            if(!expr && !(arg->expr->_mark & TM_BROKEN)
               && !(imports_from->_tags & MT_STANDARD_MODULE)) {
                arg->expr->_mark |= TM_BROKEN;
                if(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);
                }
            }
        */

            /* Search inside the IMPORTS section of the given module */
            imports_from =
                asn1f_lookup_in_imports(arg, ns_el->u.space.module, identifier);
            if(imports_from) {

                if(namespace_switches++ > 10 /* Arbitrary constant */) {
                    FATAL(
                        "Excessive circular referencing detected in namespace "
                        "%s for %s at "
                        "line %d",
                        asn1_namespace_string(arg->ns),
                        asn1f_printable_reference(ref), ref->_lineno);
                    errno = ETOOMANYREFS;
                    return NULL;
                }

                /* Switch namespace */
                DISPOSE_OF_MY_NAMESPACE();
                my_namespace = asn1_namespace_new_from_module(imports_from, 1);
                DEBUG("Lookup (%s) in %s for line %d",
                      asn1f_printable_reference(ref),
                      asn1_namespace_string(my_namespace), ref->_lineno);
                ns_item = my_namespace->elements_count;

                continue;
            } else if(errno != ESRCH) {
                /*
                 * Return only if the name was not found.
                 * If module was not found or more serious error
                 * encountered, just return preserving the errno.
                 */
                DISPOSE_OF_MY_NAMESPACE();
                return NULL;
            }

            if(modulename) {
                FATAL(
                    "Module %s referred by %s in module %s "
                    "does not contain the requested symbol",
                    ns_el->u.space.module->ModuleName,
                    asn1f_printable_reference(ref), modulename);
                break;
            }

            /* Search failed in the given namespace */
            continue;
        }
    }

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

    DISPOSE_OF_MY_NAMESPACE();

    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_expr_t *rhs_pspecs,
                    const asn1p_ref_t *ref) {
    return asn1f_lookup_symbol_impl(arg, 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);
}

asn1p_expr_t *
asn1f_find_ancestor_type_with_PER_constraint(arg_t *arg, asn1p_expr_t *expr) {
	return asn1f_find_terminal_thing(arg, expr, FTT_CONSTR_TYPE);
}

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;

    if(arg->mod != expr->module) {
        return WITH_MODULE(expr->module,
                           asn1f_find_terminal_thing(arg, expr, what));
    }

    switch(what) {
    case FTT_TYPE:
    case FTT_CONSTR_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
           && WITH_MODULE(val_type_tc->module,
                          asn1f_look_value_in_type(arg, val_type_tc, expr))) {
            return expr;
        }
		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->rhs_pspecs, ref);
    if(tc == NULL) {
		/*
	 	 * Lookup inside the ref's module and its IMPORTS section.
	 	 */
        tc = WITH_MODULE(ref->module,
                         asn1f_lookup_symbol(arg, 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;

    if((what == FTT_CONSTR_TYPE) && (tc->constraints)) {
        return tc;
    }

    tc->_mark |= TM_RECURSION;
    expr = WITH_MODULE(tc->module, 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;
}
