#include "asn1fix_internal.h"

typedef enum field_category {
	OFC_INVALID,		/* Invalid object field category */
	OFC_TYPE,
	OFC_FIXED_TYPE_VALUE,
	OFC_VARIABLE_TYPE_VALUE,
	OFC_FIXED_TYPE_VALUE_SET,
	OFC_VARIABLE_TYPE_VALUE_SET,
	OFC_INFORMATION_OBJECT,
	OFC_INFORMATION_OBJECT_SET,
} field_category_e;

typedef enum object_category {
	OC_INVALID,
	OC_OBJECT,
	OC_OBJECTSET,
} object_category_e;

static field_category_e  asn1f_class_field_category(asn1p_expr_t *ofield);
static object_category_e asn1f_class_object_category(asn1p_expr_t *expr);
static asn1p_expr_t *
asn1f_class_dot_lookup(arg_t *arg, asn1p_expr_t *obj, asn1p_ref_t *ref);

asn1p_expr_t *
asn1f_class_access(arg_t *arg, asn1p_ref_t *ref, asn1p_module_t **mod_r) {
	asn1p_expr_t *obj;		/* Information Object or Object Set */
	object_category_e obj_cat;	/* Object category */
	//field_category_e field_cat;	/* Field category */
	asn1p_expr_t *result;
	asn1p_ref_t tmpref;

	(void)mod_r;	/* Unused argument */

	assert(ref->comp_count > 1);

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

	/*
	 * Fetch the first part of the reference (OBJECT or ObjectSet).
	 * OBJECT.&<something>...
	 * ObjectSet.&<something>...
	 */
	assert(isupper(ref->components[0].name[0]));

	tmpref = *ref;
	tmpref.comp_count = 1;
	obj = asn1f_lookup_symbol(arg, &tmpref, 0);
	if(obj == NULL) {
		errno = ESRCH;
		return NULL;
	}

	/*
	 * Make sure the symbol lexical property (upper-case, lower-case)
	 * corresponds to the type of the expression returned by
	 * lookup_symbol().
	 */
	obj_cat = asn1f_class_object_category(obj);
	switch(obj_cat) {
	case OC_OBJECT:
	case OC_OBJECTSET:
		if(ref->components[0].lex_type
			== (obj_cat==OC_OBJECT)
				? RLT_CAPITALS
				: RLT_Uppercase)
			break;
		/* Fall through */
	case OC_INVALID:
		WARNING("Symbol \"%s\" is not compatible "
			"with referenced expression \"%s\" at line %d",
			ref->components[0].name,
			obj->Identifier, obj->_lineno);
		errno = EPERM;
		return NULL;
	}

	/*
	 * Find the specified field within the object.
	 */
	result = asn1f_class_dot_lookup(arg, obj, ref);
	if(result == NULL) {
		return NULL;
	}

	//field_cat = asn1f_class_field_category(result);

	DEBUG("FILLME: %s", result->Identifier);

	return result;
}

static object_category_e
asn1f_class_object_category(asn1p_expr_t *expr) {

	switch(expr->meta_type) {
	case AMT_OBJECT:
		return OC_OBJECT;
	case AMT_OBJECTSET:
		return OC_OBJECTSET;
	case AMT_VALUESET:
		if(expr->expr_type == A1TC_REFERENCE
		&& expr->reference
		&& expr->reference->comp_count == 1
		&& expr->reference->components[0].lex_type == RLT_CAPITALS)
		{
			/* FIXME: use find_terminal_type instead! */
			return OC_OBJECTSET;
		}
		break;
	default:
		break;
	}

	return OC_INVALID;
}

static field_category_e
asn1f_class_field_category(asn1p_expr_t *ofield) {
	if(ofield->Identifier[0] != '&') {
		assert(ofield->Identifier[0] == '&');
		return OFC_INVALID;
	}

	if(isupper(ofield->Identifier[1])) {
		if(ofield->reference) {
			enum asn1p_ref_lex_type_e lex_type
				= ofield->reference->components[0].lex_type;

			switch(lex_type) {
			case RLT_CAPITALS:
				return OFC_INFORMATION_OBJECT_SET;
			case RLT_Uppercase:
				return OFC_FIXED_TYPE_VALUE_SET;
			case RLT_AmpUppercase:
				return OFC_VARIABLE_TYPE_VALUE_SET;
			default:
				break;
			}
		} else {
			if(ofield->expr_type == A1TC_CLASSFIELD)
				return OFC_TYPE;

			switch(ofield->meta_type) {
			case AMT_TYPE:
			case AMT_TYPEREF:
				return OFC_FIXED_TYPE_VALUE_SET;
			default:
				break;
			}

		}
	} else {
		if(ofield->reference) {
			enum asn1p_ref_lex_type_e lex_type
				= ofield->reference->components[0].lex_type;

			switch(lex_type) {
			case RLT_CAPITALS:
				return OFC_INFORMATION_OBJECT;
			case RLT_Uppercase:
				return OFC_FIXED_TYPE_VALUE;
			case RLT_AmpUppercase:
				return OFC_VARIABLE_TYPE_VALUE;
			default:
				break;
			}
		} else {
			switch(ofield->meta_type) {
			case AMT_TYPE:
			case AMT_TYPEREF:
				return OFC_FIXED_TYPE_VALUE;
			default:
				break;
			}
		}
	}

	return OFC_INVALID;
}


static asn1p_expr_t *
asn1f_class_dot_lookup(arg_t *arg, asn1p_expr_t *obj, asn1p_ref_t *ref) {
	asn1p_expr_t *ofield = NULL;	/* Information Object's Field */
	field_category_e field_cat;	/* Field category */
	int comp;

	assert(ref->comp_count >= 2);

	for(comp = 1 /* sic! */; comp < ref->comp_count; comp++) {
		int is_last_component = (comp + 1 == ref->comp_count);
		char *comp_name = ref->components[comp].name;

		ofield = asn1f_lookup_child(obj, comp_name);
		if(ofield == NULL) {
			DEBUG("Cannot find field \"%s\" in \"%s\" at line %d",
				ref->components[1].name,
				obj->Identifier,
				obj->_lineno);
		}

		/*
		 * Compute the category of the field of
		 * the information object class.
		 */
		field_cat = asn1f_class_field_category(ofield);

		switch(field_cat) {
		case OFC_INVALID:
			WARNING("Invalid field category of \"%s\" at line %d",
				ofield->Identifier, ofield->_lineno);
			errno = EPERM;
			return NULL;
		case OFC_TYPE:
		case OFC_FIXED_TYPE_VALUE:
		case OFC_VARIABLE_TYPE_VALUE:
		case OFC_FIXED_TYPE_VALUE_SET:
		case OFC_VARIABLE_TYPE_VALUE_SET:
			if(!is_last_component) {
				FATAL("Field name component \"%s\" at line %d "
					"specifies non-dereferenceable thing",
					comp_name, ref->_lineno);
				errno = EPERM;
				return NULL;
			}
			break;
		case OFC_INFORMATION_OBJECT:
		case OFC_INFORMATION_OBJECT_SET:
			obj = ofield;
			break;
		}
	}

	assert(ofield);
	return ofield;
}
