#include "asn1c_internal.h"
#include "asn1c_constraint.h"
#include "asn1c_misc.h"
#include "asn1c_out.h"

#include <asn1fix_crange.h>	/* constraint groker from libasn1fix */
#include <asn1fix_export.h>	/* other exportables from libasn1fix */

static int asn1c_emit_constraint_tables(arg_t *arg, int got_size);
static int emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range);
static int emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_range_t *r_value);
static int emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype);
static asn1p_expr_type_e _find_terminal_type(arg_t *arg);
static int emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1c_integer_t natural_start, asn1c_integer_t natural_stop);

int
asn1c_emit_constraint_checking_code(arg_t *arg) {
	asn1cnst_range_t *r_size;
	asn1cnst_range_t *r_value;
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_type_e etype;
	asn1p_constraint_t *ct;
	int got_something = 0;
	int alphabet_table_compiled;
	int produce_st = 0;

	ct = expr->combined_constraints;
	if(ct == NULL)
		return 1;	/* No additional constraints defined */

	etype = _find_terminal_type(arg);

	r_value=asn1constraint_compute_PER_range(etype, ct, ACT_EL_RANGE,0,0,0);
	r_size = asn1constraint_compute_PER_range(etype, ct, ACT_CT_SIZE,0,0,0);
	if(r_value) {
		if(r_value->incompatible
		|| r_value->empty_constraint
		|| (r_value->left.type == ARE_MIN
			&& r_value->right.type == ARE_MAX)
		|| (etype == ASN_BASIC_BOOLEAN
			&& r_value->left.value == 0
			&& r_value->right.value == 1)
		) {
			asn1constraint_range_free(r_value);
			r_value = 0;
		}
	}
	if(r_size) {
		if(r_size->incompatible
		|| r_size->empty_constraint
		|| (r_size->left.value == 0	/* or .type == MIN */
			&& r_size->right.type == ARE_MAX)
		) {
			asn1constraint_range_free(r_size);
			r_size = 0;
		}
	}

	/*
	 * Do we really need an "*st = sptr" pointer?
	 */
	switch(etype) {
	case ASN_BASIC_INTEGER:
	case ASN_BASIC_ENUMERATED:
		if(asn1c_type_fits_long(arg, arg->expr) == FL_NOTFIT)
			produce_st = 1;
		break;
	case ASN_BASIC_REAL:
		if(!(arg->flags & A1C_USE_NATIVE_TYPES))
			produce_st = 1;
		break;
	case ASN_BASIC_BIT_STRING:
	case ASN_BASIC_OCTET_STRING:
		produce_st = 1;
			break;
	default:
		if(etype & ASN_STRING_MASK)
			produce_st = 1;
		break;
	}
	if(produce_st) {
		char *tname = asn1c_type_name(arg, arg->expr, TNF_SAFE);
		OUT("const %s_t *st = (const %s_t *)sptr;\n", tname, tname);
	}

	if(r_size || r_value) {
		if(r_size) {
			OUT("size_t size;\n");
		}
		if(r_value)
			switch(etype) {
			case ASN_BASIC_INTEGER:
			case ASN_BASIC_ENUMERATED:
				OUT("long value;\n");
				break;
			case ASN_BASIC_REAL:
				OUT("double value;\n");
				break;
			case ASN_BASIC_BOOLEAN:
				OUT("BOOLEAN_t value;\n");
				break;
			default:
				break;
		}
	}

	OUT("\n");

	/*
	 * Protection against null input.
	 */
	OUT("if(!sptr) {\n");
		INDENT(+1);
		OUT("_ASN_CTFAIL(app_key, td, sptr,\n");
		OUT("\t\"%%s: value not given (%%s:%%d)\",\n");
		OUT("\ttd->name, __FILE__, __LINE__);\n");
		OUT("return -1;\n");
		INDENT(-1);
	OUT("}\n");
	OUT("\n");

	if(r_value)
		emit_value_determination_code(arg, etype, r_value);
	if(r_size)
		emit_size_determination_code(arg, etype);

	INDENT(-1);
	REDIR(OT_CTABLES);
	/* Emit FROM() tables */
	alphabet_table_compiled =
		(asn1c_emit_constraint_tables(arg, r_size?1:0) == 1);
	REDIR(OT_CODE);
	INDENT(+1);

	/*
	 * Here is an if() {} else {} constaint checking code.
	 */
	OUT("\n");
	OUT("if(");
	INDENT(+1);
		if(r_size) {
			if(got_something++) { OUT("\n"); OUT(" && "); }
			OUT("(");
			emit_range_comparison_code(arg, r_size, "size", 0, -1);
			OUT(")");
		}
		if(r_value) {
			if(got_something++) { OUT("\n"); OUT(" && "); }
			OUT("(");
			if(etype == ASN_BASIC_BOOLEAN)
				emit_range_comparison_code(arg, r_value,
					"value", 0, 1);
			else
				emit_range_comparison_code(arg, r_value,
					"value", -1, -1);
			OUT(")");
		}
		if(alphabet_table_compiled) {
			if(got_something++) { OUT("\n"); OUT(" && "); }
			OUT("!check_permitted_alphabet_%d(%s)",
				arg->expr->_type_unique_index,
				produce_st ? "st" : "sptr");
		}
		if(!got_something) {
			OUT("1 /* No applicable constraints whatsoever */");
			OUT(") {\n");
			INDENT(-1);
			INDENTED(OUT("/* Nothing is here. See below */\n"));
			OUT("}\n");
			OUT("\n");
			return 1;
		}
	INDENT(-1);
	OUT(") {\n");
		INDENT(+1);
		switch(etype) {
		case ASN_CONSTR_SEQUENCE_OF:
		case ASN_CONSTR_SET_OF:
			OUT("/* Perform validation of the inner elements */\n");
			OUT("return td->check_constraints(td, sptr, ctfailcb, app_key);\n");
			break;
		default:
			OUT("/* Constraint check succeeded */\n");
			OUT("return 0;\n");
		}
		INDENT(-1);
	OUT("} else {\n");
		INDENT(+1);
			OUT("_ASN_CTFAIL(app_key, td, sptr,\n");
			OUT("\t\"%%s: constraint failed (%%s:%%d)\",\n");
			OUT("\ttd->name, __FILE__, __LINE__);\n");
			OUT("return -1;\n");
		INDENT(-1);
	OUT("}\n");

	return 0;
}

static int
asn1c_emit_constraint_tables(arg_t *arg, int got_size) {
	asn1c_integer_t range_start;
	asn1c_integer_t range_stop;
	asn1p_expr_type_e etype;
	asn1cnst_range_t *range;
	asn1p_constraint_t *ct;
	int utf8_full_alphabet_check = 0;
	int max_table_size = 256;
	int table[256];
	int use_table;

	ct = arg->expr->combined_constraints;
	if(!ct) return 0;

	etype = _find_terminal_type(arg);

	range = asn1constraint_compute_PER_range(etype, ct, ACT_CT_FROM, 0,0,0);
	if(!range) return 0;

	if(range->incompatible
	|| range->empty_constraint) {
		asn1constraint_range_free(range);
		return 0;
	}


	if(range->left.type == ARE_MIN
	&& range->right.type == ARE_MAX) {
		/*
		 * The permitted alphabet constraint checker code guarantees
		 * that either both bounds (left/right) are present, or
		 * they're absent simultaneously. Thus, this assertion
		 * legitimately holds true.
		 */
		assert(range->el_count == 0);
		/* The full range is specified. Ignore it. */
		return 0;
	}

	range_start = range->left.value;
	range_stop = range->right.value;
	assert(range->left.type == ARE_VALUE);
	assert(range->right.type == ARE_VALUE);
	assert(range_start <= range_stop);

	range_start = 0;	/* Force old behavior */

	/*
	 * Check if we need a test table to check the alphabet.
	 */
	use_table = 1;
	if(range->el_count == 0) {
		/*
		 * It's better to have a short if() check
		 * than waste 4k of table space
		 */
		use_table = 0;
	}
	if((range_stop - range_start) > 255)
		use_table = 0;
	if(etype == ASN_STRING_UTF8String) {
		if(range_stop >= 0x80)
			use_table = 0;
		else
			max_table_size = 128;
	}

	if(use_table) {
		int i, n = 0;
		int untl;
		memset(table, 0, sizeof(table));
		for(i = -1; i < range->el_count; i++) {
			asn1cnst_range_t *r;
			asn1c_integer_t v;
			if(i == -1) {
				if(range->el_count) continue;
				r = range;
			} else {
				r = range->elements[i];
			}
			for(v = r->left.value; v <= r->right.value; v++) {
				assert((v - range_start) >= 0);
				assert((v - range_start) < max_table_size);
				table[v - range_start] = ++n;
			}
		}

		untl = (range_stop - range_start) + 1;
		untl += (untl % 16)?16 - (untl % 16):0;
		OUT("static int permitted_alphabet_table_%d[%d] = {\n",
			arg->expr->_type_unique_index, max_table_size);
		for(n = 0; n < untl; n++) {
			OUT("%d,", table[n]?1:0);
			if(!((n+1) % 16)) {
				int c;
				if(!n) {
					OUT("\n");
					continue;
				}
				OUT("\t/* ");
				for(c = n - 15; c <= n; c++) {
					if(table[c]) {
						int a = c + range_start;
						if(a > 0x20 && a < 0x80)
							OUT("%c", a);
						else
							OUT(".");
					} else {
						OUT(" ");
					}
				}
				OUT(" */");
				OUT("\n");
			}
		}
		OUT("};\n");
		OUT("\n");
	} else if(etype == ASN_STRING_UTF8String) {
		/*
		 * UTF8String type is a special case in many respects.
		 */
		if(got_size) {
			/*
			 * Size has been already determined.
			 * The UTF8String length checker also checks
			 * for the syntax validity, so we don't have
			 * to repeat this process twice.
			 */
			asn1constraint_range_free(range);
			return 0;
		} else {
			utf8_full_alphabet_check = 1;
		}
	} else {
		/*
		 * This permitted alphabet check will be
		 * expressed using conditional statements
		 * instead of table lookups. Table would be
		 * to large or otherwise inappropriate (too sparse?).
		 */
	}

	OUT("static int check_permitted_alphabet_%d(const void *sptr) {\n",
			arg->expr->_type_unique_index);
	INDENT(+1);
	if(utf8_full_alphabet_check) {
		OUT("if(UTF8String_length((const UTF8String_t *)sptr) < 0)\n");
		OUT("\treturn -1; /* Alphabet (sic!) test failed. */\n");
		OUT("\n");
	} else {
		if(use_table) {
			OUT("int *table = permitted_alphabet_table_%d;\n",
				arg->expr->_type_unique_index);
			emit_alphabet_check_loop(arg, 0);
		} else {
			emit_alphabet_check_loop(arg, range);
		}
	}
	OUT("return 0;\n");
	INDENT(-1);
	OUT("}\n");
	OUT("\n");

	asn1constraint_range_free(range);

	return 1;
}

static int
emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range) {
	asn1c_integer_t natural_stop;
	asn1p_expr_t *terminal;
	char *tname;

	terminal = asn1f_find_terminal_type_ex(arg->asn, arg->expr);
	if(terminal) {
		OUT("/* The underlying type is %s */\n",
			ASN_EXPR_TYPE2STR(terminal->expr_type));
	} else {
		terminal = arg->expr;
	}
	tname = asn1c_type_name(arg, terminal, TNF_SAFE);
	OUT("const %s_t *st = (const %s_t *)sptr;\n", tname, tname);

	switch(terminal->expr_type) {
	case ASN_STRING_UTF8String:
		OUT("const uint8_t *ch = st->buf;\n");
		OUT("const uint8_t *end = ch + st->size;\n");
		OUT("\n");
		OUT("for(; ch < end; ch++) {\n");
			INDENT(+1);
			OUT("uint8_t cv = *ch;\n");
			if(!range) OUT("if(cv >= 0x80) return -1;\n");
		natural_stop = 0xffffffffUL;
		break;
	case ASN_STRING_UniversalString:
		OUT("const uint8_t *ch = st->buf;\n");
		OUT("const uint8_t *end = ch + st->size;\n");
		OUT("\n");
		OUT("if(st->size %% 4) return -1; /* (size%%4)! */\n");
		OUT("for(; ch < end; ch += 4) {\n");
			INDENT(+1);
			OUT("uint32_t cv = (ch[0] << 24)\n");
			OUT("\t\t| (ch[1] << 16)\n");
			OUT("\t\t| (ch[2] << 8)\n");
			OUT("\t\t|  ch[3];\n");
			if(!range) OUT("if(cv > 255) return -1;\n");
		natural_stop = 0xffffffffUL;
		break;
	case ASN_STRING_BMPString:
		OUT("const uint8_t *ch = st->buf;\n");
		OUT("const uint8_t *end = ch + st->size;\n");
		OUT("\n");
		OUT("if(st->size %% 2) return -1; /* (size%%2)! */\n");
		OUT("for(; ch < end; ch += 2) {\n");
			INDENT(+1);
			OUT("uint16_t cv = (ch[0] << 8)\n");
			OUT("\t\t| ch[1];\n");
			if(!range) OUT("if(cv > 255) return -1;\n");
		natural_stop = 0xffff;
		break;
	case ASN_BASIC_OCTET_STRING:
	default:
		OUT("const uint8_t *ch = st->buf;\n");
		OUT("const uint8_t *end = ch + st->size;\n");
		OUT("\n");
		OUT("for(; ch < end; ch++) {\n");
			INDENT(+1);
			OUT("uint8_t cv = *ch;\n");
		natural_stop = 0xff;
		break;
	}

	if(range) {
		OUT("if(!(");
		emit_range_comparison_code(arg, range, "cv", 0, natural_stop);
		OUT(")) return -1;\n");
	} else {
		OUT("if(!table[cv]) return -1;\n");
	}

	INDENT(-1);
	OUT("}\n");

	return 0;
}

static int
emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1c_integer_t natural_start, asn1c_integer_t natural_stop) {
	int ignore_left;
	int ignore_right;
	int generated_something = 0;
	int i;

	for(i = -1; i < range->el_count; i++) {
		asn1cnst_range_t *r;
		if(i == -1) {
			if(range->el_count) continue;
			r = range;
		} else {
			if(i) OUT(" || ");
			r = range->elements[i];
		}

		if(r != range) OUT("(");

		ignore_left = (r->left.type == ARE_MIN)
				|| (natural_start != -1
					&& r->left.value <= natural_start);
		ignore_right = (r->right.type == ARE_MAX)
				|| (natural_stop != -1
					&& r->right.value >= natural_stop);
		if(ignore_left && ignore_right) {
			OUT("1 /* Constraint matches natural range of %s */",
				varname);
			continue;
		}

		if(ignore_left) {
			OUT("%s <= %" PRIdASN, varname,
				r->right.value);
		} else if(ignore_right) {
			OUT("%s >= %" PRIdASN, varname,
				r->left.value);
		} else if(r->left.value == r->right.value) {
			OUT("%s == %" PRIdASN, varname,
				r->right.value);
		} else {
			OUT("%s >= %" PRIdASN " && %s <= %" PRIdASN,
				varname,
				r->left.value,
				varname,
				r->right.value);
		}
		if(r != range) OUT(")");
		generated_something = 1;
	}

	return generated_something;
}

static int
emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype) {

	switch(etype) {
	case ASN_BASIC_BIT_STRING:
		OUT("if(st->size > 0) {\n");
		OUT("\t/* Size in bits */\n");
		OUT("\tsize = 8 * st->size - (st->bits_unused & 0x07);\n");
		OUT("} else {\n");
		OUT("\tsize = 0;\n");
		OUT("}\n");
		break;
	case ASN_STRING_UniversalString:
		OUT("size = st->size >> 2;\t/* 4 byte per character */\n");
		break;
	case ASN_STRING_BMPString:
		OUT("size = st->size >> 1;\t/* 2 byte per character */\n");
		break;
	case ASN_STRING_UTF8String:
		OUT("size = UTF8String_length(st);\n");
		OUT("if((ssize_t)size < 0) {\n");
		OUT("\t_ASN_CTFAIL(app_key, td, sptr,\n");
		OUT("\t\t\"%%s: UTF-8: broken encoding (%%s:%%d)\",\n");
		OUT("\t\ttd->name, __FILE__, __LINE__);\n");
		OUT("\treturn -1;\n");
		OUT("}\n");
		break;
	case ASN_CONSTR_SET_OF:
	case ASN_CONSTR_SEQUENCE_OF:
		OUT("/* Determine the number of elements */\n");
		OUT("size = _A_C%s_FROM_VOID(sptr)->count;\n",
			etype==ASN_CONSTR_SET_OF?"SET":"SEQUENCE");
		break;
	case ASN_BASIC_OCTET_STRING:
		OUT("size = st->size;\n");
		break;
	default:
		if(etype & ASN_STRING_MASK) {
			OUT("size = st->size;\n");
			break;
		} else {
			const char *type_name = ASN_EXPR_TYPE2STR(etype);
			if(!type_name) type_name = arg->expr->Identifier;
			WARNING("SizeConstraint is not defined for %s",
				type_name);
			OUT_NOINDENT("#warning SizeConstraint "
				"is not defined for %s!\n", type_name);
			OUT("size = st->size;\n");
		}
		return -1;
	}

	return 0;
}

static int
emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_range_t *r_value) {

	switch(etype) {
	case ASN_BASIC_INTEGER:
	case ASN_BASIC_ENUMERATED:
		if(asn1c_type_fits_long(arg, arg->expr) != FL_NOTFIT) {
			OUT("value = *(const long *)sptr;\n");
		} else {
			if(r_value->el_count == 0
			&& (
				/* Speed-up common case: (0..MAX) */
				(r_value->left.type == ARE_VALUE
				&& r_value->left.value == 0
				&& r_value->right.type == ARE_MAX)
			    ||
				/* Speed-up common case: (MIN..-1) */
				(r_value->left.type == ARE_MIN
				&& r_value->right.type == ARE_VALUE
				&& r_value->right.value == -1)
			)) {
				OUT("/* Check if the sign bit is present */\n");
				OUT("value = st->buf ? ((st->buf[0] & 0x80) ? -1 : 1) : 0;\n");
				break;
			}

			OUT("if(asn_INTEGER2long(st, &value)) {\n");
				INDENT(+1);
				OUT("_ASN_CTFAIL(app_key, td, sptr,\n");
				OUT("\t\"%%s: value too large (%%s:%%d)\",\n");
				OUT("\ttd->name, __FILE__, __LINE__);\n");
				OUT("return -1;\n");
				INDENT(-1);
			OUT("}\n");
		}
		break;
	case ASN_BASIC_REAL:
		if(arg->flags & A1C_USE_NATIVE_TYPES) {
			OUT("value = *(const double *)sptr;\n");
		} else {
			OUT("if(asn_REAL2double(st, &value)) {\n");
				INDENT(+1);
				OUT("_ASN_CTFAIL(app_key, td, sptr,\n");
				OUT("\t\"%%s: value too large (%%s:%%d)\",\n");
				OUT("\ttd->name, __FILE__, __LINE__);\n");
				OUT("return -1;\n");
				INDENT(-1);
			OUT("}\n");
		}
		break;
	case ASN_BASIC_BOOLEAN:
		OUT("value = (*(const long *)sptr) ? 1 : 0;\n");
		break;
	default:
		WARNING("%s:%d: Value cannot be determined "
			"for constraint check for %s",
			arg->expr->module->source_file_name,
			arg->expr->_lineno,
			arg->expr->Identifier
		);
		OUT_NOINDENT(
			"#error %s:%d: Value of %s cannot be determined\n",
			arg->expr->module->source_file_name,
			arg->expr->_lineno,
			arg->expr->Identifier
		);
		break;
	}

	return 0;
}

static asn1p_expr_type_e
_find_terminal_type(arg_t *arg) {
	asn1p_expr_t *expr;
	expr = asn1f_find_terminal_type_ex(arg->asn, arg->expr);
	if(expr) return expr->expr_type;
	return A1TC_INVALID;
}

