#include "asn1fix_internal.h"

int asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype);
static void asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value);
static int asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype);

int
asn1f_fix_bit_string(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	int r_value = 0;
	int ret;

	if(expr->meta_type == AMT_VALUE) {
		asn1p_expr_t *ttype;

		DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno);

		ttype = asn1f_find_terminal_type(arg, expr);
		if(ttype && ttype->expr_type == ASN_BASIC_BIT_STRING) {
			ret = asn1f_fix_bit_string_value(arg, ttype);
			RET2RVAL(ret, r_value);
		}
	}

	return r_value;
}

int
asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype) {
	asn1p_expr_t *expr = arg->expr;
	int r_value = 0;

	DEBUG("(%s) for line %d",
		expr->Identifier, expr->_lineno);

	switch(expr->value->type) {
	case ATV_UNPARSED:
		/*
		 * Most definitely we have something like
		 * 	value BitStringType1 ::= { a, b, c }
		 * which could not be parsed by the LALR parser, mostly
		 * because it requires knowledge about BitStringType1
		 * during the parsing. So, here's a little hack: we create
		 * a buffer containing the full specification of a module,
		 * which contains some pre-defined INTEGER type with the
		 * opaque definition "{ a, b, c }" from the bit string.
		 */
		if(asn1f_BS_unparsed_convert(arg, expr->value, ttype)) {
			r_value = -1;
			break;
		}
		/* Fall through: remove trailing zero bits */
	case ATV_BITVECTOR:
		asn1f_BS_remove_trailing_zero_bits(expr->value);
		break;
	default:
		break;
	}

	return r_value;
}

static void
asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value) {
	int lmfb = -1;	/* Last meaningful byte position */
	int bits;	/* Number of bits in the BIT STRING value */
	int b;

	assert(value->type == ATV_BITVECTOR);

	bits = value->value.binary_vector.size_in_bits;
	/*
	 * Figure out the rightmost meaningful byte.
	 */
	for(b = 0; b < ((bits + 7) >> 3); b++) {
		uint8_t uc = value->value.binary_vector.bits[b];
		if(uc && b > lmfb)
			lmfb = b;
	}
	if(lmfb == -1) {
		bits = 0;
	} else {
		uint8_t uc;
		uc = value->value.binary_vector.bits[lmfb];
		bits = (lmfb+1) * 8;
		/*
		 * Squeeze the bit string width until the rightmost
		 * bit is set.
		 */
		for(; uc && (uc & 1) == 0; uc >>= 1)
			bits--;
		if(uc == 0) {
			bits = lmfb * 8;
		}
	}
	value->value.binary_vector.size_in_bits = bits;
}

static int
asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype) {
	asn1p_t *asn;
	asn1p_module_t *mod;
	asn1p_expr_t *V;
	asn1p_expr_t *bit;
	asn1c_integer_t aI;
	uint8_t *bitbuf;
	int bits;
	int psize;
	char *p;
	int ret;
	int r_value = 0;

	assert(value->type == ATV_UNPARSED);

	psize = value->value.string.size + 64;
	p = malloc(psize);
	if(p == NULL)
		return -1;

	ret = snprintf(p, psize,
		"M DEFINITIONS ::=\nBEGIN\n"
		"V ::= INTEGER %s\n"
		"END\n",
		value->value.string.buf
	);
	assert(ret < psize);
	psize = ret;

	asn = asn1p_parse_buffer(p, psize, A1P_NOFLAGS);
	free(p);
	if(asn == NULL) {
		FATAL("Cannot parse BIT STRING value %s "
			"defined as %s at line %d",
			arg->expr->Identifier,
			value->value.string.buf,
			arg->expr->_lineno
		);
		return -1;
	}

	mod = TQ_FIRST(&(asn->modules));
	assert(mod);
	V = TQ_FIRST(&(mod->members));
	assert(V);
	assert(strcmp(V->Identifier, "V") == 0);
	assert(TQ_FIRST(&(V->members)));

	/*
	 * Simple loop just to fetch the maximal bit position
	 * out of the BIT STRING value defined as NamedBitList.
	 */
	aI = -1;
	TQ_FOR(bit, &(V->members), next) {
		asn1p_expr_t *bitdef;
		bitdef = asn1f_lookup_child(ttype, bit->Identifier);
		if(bitdef && bitdef->value
		&& bitdef->value->type == ATV_INTEGER) {
			if(bitdef->value->value.v_integer > aI)
				aI = bitdef->value->value.v_integer;
		}
	}

	if(aI > 1024 * 1024 * 8) {	/* One megabyte */
		FATAL("Unsupportedly large BIT STRING value \"%s\" "
			"defined at line %d "
			"(larger than 1MByte)",
			arg->expr->Identifier,
			arg->expr->_lineno
		);
		asn1p_free(asn);
		return -1;
	}

	bits = aI + 1;	/* Number of bits is more than a last bit position */
	bitbuf = calloc(1, 1 + ((bits + 7) / 8));
	if(bitbuf == NULL) {
		asn1p_free(asn);
		return -1;
	}

	TQ_FOR(bit, &(V->members), next) {
		asn1p_expr_t *bitdef;
		int set_bit_pos;

		if(bit->value) {
			WARNING("Identifier \"%s\" at line %d "
				"must not have a value",
				bit->Identifier, bit->_lineno);
			RET2RVAL(1, r_value);
		}
		bitdef = asn1f_lookup_child(ttype, bit->Identifier);
		if(bitdef == NULL) {
			FATAL("Identifier \"%s\" at line %d is not defined "
				"in the \"%s\" type definition at line %d",
				bit->Identifier,
				bit->_lineno,
				ttype->Identifier,
				ttype->_lineno
			);
			RET2RVAL(-1, r_value);
			continue;
		}
		if(bitdef->value == NULL
		|| bitdef->value->type != ATV_INTEGER) {
			FATAL("Broken identifier "
				"\"%s\" at line %d "
				"referenced by \"%s\" at line %d",
				bitdef->Identifier,
				bitdef->_lineno,
				arg->expr->Identifier,
				arg->expr->_lineno
			);
			RET2RVAL(-1, r_value);
			continue;
		}

		assert(bitdef->value->value.v_integer < bits);
		set_bit_pos = bitdef->value->value.v_integer;
		bitbuf[set_bit_pos>>3] |= 1 << (7-(set_bit_pos % 8));
	}

	asn1p_free(asn);
	free(value->value.string.buf);
	value->type = ATV_BITVECTOR;
	value->value.binary_vector.bits = bitbuf;
	value->value.binary_vector.size_in_bits = bits;

	return r_value;
}
