#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,
		const uint8_t *buf, const uint8_t *bend,
		int optional_mode, const uint8_t **newpos, int counter);
static int _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell, const uint8_t *buf, const uint8_t *bend, int counter);
static asn1p_wsyntx_chunk_t *asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf);

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

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

	eclass = asn1f_find_terminal_type(arg, expr);
	if(!eclass
	|| eclass->meta_type != AMT_OBJECTCLASS
	|| eclass->expr_type != A1TC_CLASSDEF) {
		return 0;
	}

	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, 0);

	asn1p_ioc_row_delete(row);

	return ret;
}

static int
_asn1f_is_ioc_row_duplicate(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
    if(!it) {
        return 0;
    }

    for(size_t i = 0; i < it->rows; i++) {
        switch(asn1p_ioc_row_match(it->row[i], row)) {
        default:
        case -1:
            return -1;
        case 1:
            continue;
        case 0:
            return 1; /* Duplicate! */
        }
    }
    return 0;
}

struct parse_object_key {
    arg_t *arg;
    asn1p_expr_t *expr;   /* InformationObjectSet */
    asn1p_expr_t *eclass; /* CLASS */
    int sequence;          /* Sequence counter */
};

/*
 * Add to the IoC table if the row is unique.
 */
static int
_asn1f_add_unique_row(arg_t *arg, asn1p_expr_t *expr, asn1p_ioc_row_t *row) {
    assert(expr->ioc_table);

    /* Look for duplicates */
    switch(_asn1f_is_ioc_row_duplicate(expr->ioc_table, row)) {
    case -1:
        DEBUG("Found Information Object Duplicate in %s", expr->Identifier,
              expr->_lineno);
        return -1;
    case 0:
        /* Not a duplicate */
        break;
    case 1:
        /* Proper duplicate detected; ignore */
        asn1p_ioc_row_delete(row);
        return 0;
        }

    asn1p_ioc_table_add(expr->ioc_table, row);

    return 0;
}

/*
 * Given a single blob of unparsed Information Object specification, parse it
 * into a given InformationObjectSet.
 */
static int
_asn1f_parse_object_cb(const uint8_t *buf, size_t size, void *keyp) {
    struct parse_object_key *key = keyp;
    arg_t *arg = key->arg;
    asn1p_expr_t *expr = key->expr;
    asn1p_expr_t *eclass = key->eclass;
	asn1p_ioc_row_t *row;
    int ret;

    key->sequence++;

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

    ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
                                         buf, buf + size, 0, 0, key->sequence);
    if(ret) {
		LOG((int)(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;
	}

    /* Add object to a CLASS. */
    if(_asn1f_add_unique_row(arg, eclass, row) != 0)
        return -1;

    /*
     * Add a copy of the object to the Information Object Set.
     */
	row = asn1p_ioc_row_new(eclass);
	assert(row);
    ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
                                         buf, buf + size, 0, 0, key->sequence);
    assert(ret == 0);

    if(_asn1f_add_unique_row(arg, expr, row) != 0)
        return -1;

    return 0;
}

static int
_asn1f_foreach_unparsed_union(const asn1p_constraint_t *ct_union,
                              int (*process)(const uint8_t *buf, size_t size,
                                             void *key),
                              void *key) {
    assert(ct_union->type == ACT_CA_UNI);

    for(size_t j = 0; j < ct_union->el_count; j++) {
        const asn1p_constraint_t *ct2 = ct_union->elements[j];
        if(ct2->type == ACT_EL_VALUE && ct2->value->type == ATV_UNPARSED) {
            if(process
               && process(ct2->value->value.string.buf + 1,
                          ct2->value->value.string.size - 2, key)
                      != 0) {
                return -1;
            }
            continue;
        }
        return -1;
    }

    return 0;
}

static int
_asn1f_foreach_unparsed(arg_t *arg, const asn1p_constraint_t *ct,
                        int (*process)(const uint8_t *buf, size_t size,
                                       void *key),
                        void *keyp) {
    struct parse_object_key *key = keyp;
    if(!ct) return -1;

    switch(ct->type) {
    default:
        DEBUG("Constraint is of unknown type %d for CWS", ct->type);
        return -1;
    case ACT_EL_EXT:    /* ... */
        if(key) {
            key->expr->ioc_table->extensible = 1;
        }
        return 0;
    case ACT_CA_UNI:    /* | */
        return _asn1f_foreach_unparsed_union(ct, process, keyp);
    case ACT_CA_CSV:    /* , */
        break;
    }

    for(size_t i = 0; i < ct->el_count; i++) {
        const asn1p_constraint_t *ct1 = ct->elements[i];
        if(_asn1f_foreach_unparsed(arg, ct1, process, keyp) != 0) {
            return -1;
        }
    }

    return 0;
}

static int
_asn1f_constraint_looks_like_object_set(arg_t *arg,
                                        const asn1p_constraint_t *ct) {
    return 0 == _asn1f_foreach_unparsed(arg, ct, NULL, NULL);
}

int
asn1f_parse_class_object(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *eclass;
    enum {
        FROM_VALUE,
        FROM_CONSTRAINT,
    } source = FROM_VALUE;

	if(expr->meta_type == AMT_VALUE
	&& expr->expr_type == A1TC_REFERENCE
	&& expr->value && expr->value->type == ATV_UNPARSED) {
        source = FROM_VALUE;
    } else if(expr->meta_type != AMT_VALUESET
	|| expr->expr_type != A1TC_REFERENCE) {
        return 0;
    } else if(expr->value && expr->value->type == ATV_UNPARSED) {
        source = FROM_VALUE;
    } else if(!expr->value) {
        if(_asn1f_constraint_looks_like_object_set(arg, expr->constraints)) {
            source = FROM_CONSTRAINT;
        } else {
            return 0;
        }
    } else {
        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;
	}

    struct parse_object_key key = {
        .arg = arg,
        .expr = expr,
        .eclass = eclass,
        .sequence = 0
    };

    if(!expr->ioc_table) {
        expr->ioc_table = asn1p_ioc_table_new();
    }

    if(!eclass->ioc_table) {
        eclass->ioc_table = asn1p_ioc_table_new();
    }

    switch(source) {
    case FROM_VALUE:
        if(_asn1f_parse_object_cb(expr->value->value.string.buf + 1,
                           expr->value->value.string.size - 2, &key)
           != 0) {
            return -1;
        }
        break;
    case FROM_CONSTRAINT:
        if(_asn1f_foreach_unparsed(arg, expr->constraints,
                                   _asn1f_parse_object_cb, &key)
           != 0) {
            return -1;
        }
    }

	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,
		const uint8_t *buf, const uint8_t *bend,
		int optional_mode, const uint8_t **newpos, int counter) {
	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;
			asn1p_wsyntx_chunk_t *next_literal;
			const uint8_t *buf_old = buf;
			const uint8_t *p = 0;

			SKIPSPACES;

			next_literal = asn1f_next_literal_chunk(syntax, chunk, buf);
			if(!next_literal) {
				p += (bend - p);
			} else {
				p = (uint8_t *)strstr((const char *)buf, (const char *)next_literal->content.token);
				if(!p) {
					if (!optional_mode)
						FATAL("Next literal \"%s\" not found !", next_literal->content.token);

					if(newpos) *newpos = buf_old;
					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, cell, buf, p, counter);
			if(ret) return ret;
			buf = p;
			if(newpos) *newpos = buf;
		    } break;
		case WC_OPTIONALGROUP: {
			const uint8_t *np = 0;
			SKIPSPACES;
			ret = _asn1f_parse_class_object_data(arg, eclass, row,
				chunk->content.syntax, buf, bend, 1, &np, counter);
			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_cell_s *cell,
                         const uint8_t *buf, const uint8_t *bend, int counter) {
    asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
	char *mivr; /* Most Immediate Value Representation */
	int new_ref = 1;
	asn1p_t *asn;
	asn1p_module_t *mod;
	asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL;
	int i, ret = 0, psize;
	char *pp;

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

	mivr = malloc(bend - buf + 1);
	assert(mivr);
	memcpy(mivr, buf, bend - buf);
	mivr[bend - buf] = '\0';
	/* remove trailing space */
	for (i = bend - buf - 1; (i > 0) && isspace(mivr[i]); i--)
		mivr[i] = '\0';

	/* This value 100 should be larger than following formatting string */
	psize = bend - buf + 100;
	pp = malloc(psize);
	if(pp == NULL) {
		free(mivr);
		return -1;
	}

	if(cell->field->expr_type == A1TC_CLASSFIELD_TFS) {
		ret = snprintf(pp, psize,
			"M DEFINITIONS ::=\nBEGIN\n"
			"V ::= %s\n"
			"END\n",
			mivr
		);
	} else if(cell->field->expr_type == A1TC_CLASSFIELD_FTVFS) {
		type_expr = TQ_FIRST(&(cell->field->members));
		ret = snprintf(pp, psize,
				"M DEFINITIONS ::=\nBEGIN\n"
				"v %s ::= %s\n"
				"END\n",
				type_expr->reference ? 
					type_expr->reference->components[0].name : 
					_asn1p_expr_type2string(type_expr->expr_type),
				mivr
			);
	} else {
		WARNING("asn1c only be able to parse TypeFieldSpec and FixedTypeValueFieldSpec. Failed when parsing %s at line %d\n", mivr, arg->expr->_lineno);
		free(mivr);
		free(pp);
		return -1;
	}
	DEBUG("ASN.1:\n\n%s\n", pp);

	assert(ret < psize);
	psize = ret;

	asn = asn1p_parse_buffer(pp, psize,
		arg->expr->module->source_file_name, arg->expr->_lineno, A1P_NOFLAGS);
	free(pp);
	if(asn == NULL) {
		FATAL("Cannot parse Setting token %s "
			"at line %d",
			mivr,
			arg->expr->_lineno
		);
		free(mivr);
		return -1;
	} else {
		mod = TQ_FIRST(&(asn->modules));
		assert(mod);
		expr = TQ_REMOVE(&(mod->members), next);
		assert(expr);

        expr->parent_expr = NULL;
        asn1p_expr_set_source(expr, arg->expr->module, arg->expr->_lineno);
        expr->_type_unique_index = counter;
        DEBUG("Parsed identifier %s, mivr [%s], reference [%s] value [%s]",
              expr->Identifier, mivr, asn1p_ref_string(expr->reference),
              asn1f_printable_value(expr->value));
        free(expr->Identifier);
        if(expr->value) {
			expr->Identifier = strdup(asn1f_printable_value(expr->value));
        } else if (expr->reference) {
			expr->Identifier = strdup(expr->reference->components[expr->reference->comp_count - 1].name);
		} else {
			expr->Identifier = mivr;
		}
		asn1p_delete(asn);
	}

	if(expr->reference &&
		!asn1f_lookup_symbol(arg, expr->rhs_pspecs, expr->reference)) {

		asn1p_ref_free(expr->reference);
		new_ref = 0;
		expr->reference = type_expr->reference;
		if (asn1f_value_resolve(arg, expr, 0)) {
			expr->reference = 0;
			asn1p_expr_free(expr);
			FATAL("Cannot find %s referenced by %s at line %d",
				mivr, arg->expr->Identifier,
				arg->expr->_lineno);
			free(mivr);
			return -1;
		}
	}

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

	cell->value = expr;
	cell->new_ref = new_ref;

	if(expr->Identifier != mivr) {
		free(mivr);
    }

	return 0;
}

static asn1p_wsyntx_chunk_t *
asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf)
{
	asn1p_wsyntx_chunk_t *next_chunk;

	next_chunk = TQ_NEXT(chunk, next);
	do {
		if(next_chunk == (struct asn1p_wsyntx_chunk_s *)0) {
			if(!syntax->parent)
				break;
			next_chunk = TQ_NEXT(syntax->parent, next);
		} else if(next_chunk->type == WC_LITERAL) {
			if(strstr((const char *)buf, (char *)next_chunk->content.token))
				break;
			if(!syntax->parent)
				break;
			next_chunk = TQ_NEXT(syntax->parent, next);
		} else if(next_chunk->type == WC_WHITESPACE) {
			next_chunk = TQ_NEXT(next_chunk, next);
		} else if(next_chunk->type == WC_OPTIONALGROUP) {
			syntax = next_chunk->content.syntax;
			next_chunk = TQ_FIRST(((&next_chunk->content.syntax->chunks)));
		} else 
			break;
	} while (next_chunk);

	return next_chunk;
}
