#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 %s just yet",
			"WITH SYNTAX");
		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;
			int lbraces = 0;
			uint8_t *p;

			SKIPSPACES;

			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) return ret;
			buf = p;
			if(newpos) *newpos = buf;
		    } 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;
			buf = np;
		    } 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;
	int idLength;
	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! Contact the asn1c author.\n", p, arg->expr->_lineno);
				return -1;
			}
			expr = asn1p_expr_new(arg->expr->_lineno, arg->expr->module);
			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; try converting %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, arg->expr->rhs_pspecs, 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;

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

	return 0;
}

