#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;

	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;
}
