#include "asn1fix_internal.h"
#include "asn1fix_cws.h"

static int _asn1f_parse_class_object_data(arg_t *, asn1p_expr_t *eclass,
		struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
		uint8_t *buf, const uint8_t *bend,
		int optional_mode, uint8_t **newpos);
static int _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_ioc_cell_s *cell, uint8_t *buf, const uint8_t *bend);

int
asn1f_parse_class_object(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *eclass;
	asn1p_ioc_row_t *row;
	void *new_rows_ptr;
	int ret;

	if(expr->meta_type != AMT_VALUE
	|| expr->expr_type != A1TC_REFERENCE
	|| !expr->value
	|| expr->value->type != ATV_UNPARSED)
		return 0;

	/*
	 * Find the governing class.
	 */
	eclass = asn1f_find_terminal_type(arg, expr);
	if(!eclass
	|| eclass->meta_type != AMT_OBJECTCLASS
	|| eclass->expr_type != A1TC_CLASSDEF) {
		return 0;
	}

	DEBUG("Value %s of CLASS %s found at line %d",
		expr->Identifier, eclass->Identifier, expr->_lineno);

	if(!eclass->with_syntax) {
		DEBUG("Can't process classes without WITH SYNTAX just yet");
		return 0;
	}

	row = asn1p_ioc_row_new(eclass);
	assert(row);

	ret = _asn1f_parse_class_object_data(arg, eclass, row,
		eclass->with_syntax,
		expr->value->value.string.buf + 1,
		expr->value->value.string.buf
			+ expr->value->value.string.size - 1,
		0, 0);
	if(ret) {
		LOG((ret < 0),
			"Cannot parse %s of CLASS %s found at line %d",
			expr->Identifier, eclass->Identifier, expr->_lineno);
		asn1p_ioc_row_delete(row);
		return ret;
	}

	new_rows_ptr = realloc(eclass->object_class_matrix.row,
			(eclass->object_class_matrix.rows + 1)
			* sizeof(eclass->object_class_matrix.row[0]));
	assert(new_rows_ptr);
	eclass->object_class_matrix.row = new_rows_ptr;
	eclass->object_class_matrix.row[eclass->object_class_matrix.rows] = row;
	eclass->object_class_matrix.rows++;
	/* Propagate max identifier length */
	if(eclass->object_class_matrix.max_identifier_length
			< row->max_identifier_length)
		eclass->object_class_matrix.max_identifier_length
			= row->max_identifier_length;

	return 0;
}

#define	SKIPSPACES	for(; buf < bend && isspace(*buf); buf++)

static int
_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
		struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
		uint8_t *buf, const uint8_t *bend,
		int optional_mode, uint8_t **newpos) {
	struct asn1p_wsyntx_chunk_s *chunk;
	int ret;

	TQ_FOR(chunk, (&syntax->chunks), next) {
		switch(chunk->type) {
		case WC_LITERAL: {
			int token_len = strlen(chunk->content.token);
			SKIPSPACES;
			if(bend - buf < token_len
			|| memcmp(buf, chunk->content.token, token_len)) {
				if(!optional_mode) {
					FATAL("While parsing object class value %s at line %d: Expected: \"%s\", found: \"%s\"",
					arg->expr->Identifier, arg->expr->_lineno, chunk->content.token, buf);
				}
				if(newpos) *newpos = buf;
				return -1;
			}
			buf += token_len;
		    } break;
		case WC_WHITESPACE: break;	/* Ignore whitespace */
		case WC_FIELD: {
			struct asn1p_ioc_cell_s *cell;
			uint8_t *p;
			SKIPSPACES;
			int lbraces = 0;
			p = buf;
			if(p < bend && *p == '{')
				lbraces = 1, p++;
			for(; p < bend; p++) {
				if(lbraces) {
					/* Search the terminating brace */
					switch(*p) {
					case '}': lbraces--; break;
					case '{': lbraces++; break;
					}
				} else if(isspace(*p)) {
					break;
				}
			}
			if(lbraces) {
				FATAL("Field reference %s found in class value definition for %s at line %d can not be satisfied by broken value \"%s\"",
				chunk->content.token,
				arg->expr->Identifier, arg->expr->_lineno, buf);
				if(newpos) *newpos = buf;
				return -1;
			}
			cell = asn1p_ioc_row_cell_fetch(row,
					chunk->content.token);
			if(cell == NULL) {
				FATAL("Field reference %s found in WITH SYNAX {} clause does not match actual field in Object Class %s",
					chunk->content.token,
					eclass->Identifier, eclass->_lineno);
				if(newpos) *newpos = buf;
				return -1;
			}
			DEBUG("Reference %s satisfied by %s (%d)",
				chunk->content.token,
				buf, p - buf);
			ret = _asn1f_assign_cell_value(arg, row, cell, buf, p);
			if(ret) {
				if(newpos) *newpos = buf;
				return ret;
			}
			buf = p;
		    } break;
		case WC_OPTIONALGROUP: {
			uint8_t *np = 0;
			SKIPSPACES;
			ret = _asn1f_parse_class_object_data(arg, eclass, row,
				chunk->content.syntax, buf, bend, 1, &np);
			if(newpos) *newpos = np;
			if(ret && np != buf)
				return ret;
		    } break;
		}
	}


	if(newpos) *newpos = buf;
	return 0;
}


static int
_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_ioc_cell_s *cell,
		uint8_t *buf, const uint8_t *bend) {
	asn1p_expr_t *expr;
	asn1p_ref_t *ref;
	char *p;

	if((bend - buf) <= 0) {
		FATAL("Assignment warning: empty string is being assigned into %s for %s at line %d",
			cell->field->Identifier,
			arg->expr->Identifier, arg->expr->_lineno);
		return -1;
	}

	p = malloc(bend - buf + 1);
	assert(p);
	memcpy(p, buf, bend - buf);
	p[bend - buf] = '\0';

	if(!isalpha(*p)) {

		if(isdigit(*p)) {
			asn1c_integer_t value;
			if(asn1p_atoi(p, &value)) {
				FATAL("Value %s at line %d is too large for this compiler! Please contact the asn1c author.\n", p, arg->expr->_lineno);
				return -1;
			}
			expr = asn1p_expr_new(arg->expr->_lineno);
			expr->Identifier = p;
			expr->meta_type = AMT_VALUE; 
			expr->expr_type = ASN_BASIC_INTEGER;
			expr->value = asn1p_value_fromint(value);
		} else {
			WARNING("asn1c is not yet able to parse arbitrary direct values; please convert %s at line %d to a reference.", p, arg->expr->_lineno);
			free(p);
			return 1;
		}
	} else {
		ref = asn1p_ref_new(arg->expr->_lineno);
		asn1p_ref_add_component(ref, p, RLT_UNKNOWN);
		assert(ref);
	
		expr = asn1f_lookup_symbol(arg, arg->mod, ref);
		if(!expr) {
			FATAL("Cannot find %s referenced by %s at line %d",
				p, arg->expr->Identifier,
				arg->expr->_lineno);
			return -1;
		}
	}

	DEBUG("Field %s assignment of %s got %s",
		cell->field->Identifier, p, expr->Identifier);

	cell->value = expr;

	if(row->max_identifier_length < strlen(expr->Identifier))
		row->max_identifier_length = strlen(expr->Identifier);

	return 0;
}

