/*-
 * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#include <constr_TYPE.h>
#include <assert.h>

#define	ADVANCE(num_bytes)	do {			\
		size_t num = num_bytes;			\
		ptr += num;				\
		size -= num;				\
		consumed_myself += num;			\
	} while(0)
#define	RETURN(_code)	do {				\
		ber_dec_rval_t rval;			\
		rval.code = _code;			\
		rval.consumed = consumed_myself;	\
		return rval;				\
	} while(0)

/*
 * The BER decoder of any type.
 */
ber_dec_rval_t
ber_decode(asn1_TYPE_descriptor_t *type_descriptor,
	void **struct_ptr, void *ptr, size_t size) {

	/*
	 * Invoke type-specific decoder.
	 */
	return type_descriptor->ber_decoder(type_descriptor,
		struct_ptr,	/* Pointer to the destination structure */
		ptr, size,	/* Buffer and its size */
		0		/* Default tag mode is 0 */
		);
}

/*
 * Check the set of <TL<TL<TL...>>> tags matches the definition.
 */
ber_dec_rval_t
ber_check_tags(asn1_TYPE_descriptor_t *head, ber_dec_ctx_t *ctx,
		void *ptr, size_t size, int tag_mode,
		ber_tlv_len_t *last_length, int *opt_tlv_form) {
	ssize_t consumed_myself = 0;
	ssize_t tag_len;
	ssize_t len_len;
	ber_tlv_tag_t tlv_tag;
	ber_tlv_len_t tlv_len;
	ber_tlv_len_t limit_len = -1;
	int expect_00_terminators = 0;
	int tlv_constr = -1;	/* If CHOICE, opt_tlv_form is not given */
	int tagno;

	/*
	 * So what does all this tags_impl_skip stuff mean?
	 * Imagine the two types,
	 * 	A ::= [5] IMPLICIT	T
	 * 	B ::= [2] EXPLICIT	T
	 * Where T is defined as
	 *	T ::= [4] IMPLICIT SEQUENCE { ... }
	 * 
	 * Let's say, we are starting to decode type A, given the
	 * following TLV stream: <5> <0>. What does this mean?
	 * It means that the type A contains type T which is,
	 * in turn, empty.
	 * Remember though, that we are still in A. We cannot
	 * just pass control to the type T decoder. Why? Because
	 * the type T decoder expects <4> <0>, not <5> <0>.
	 * So, we must make sure we are going to receive <5> while
	 * still in A, then pass control to the T decoder, indicating
	 * that the tag <4> was implicitly skipped. The decoder of T
	 * hence will be prepared to treat <4> as valid tag, and decode
	 * it appropriately.
	 */

	/*
	 * We have a list of tags that must occur in the stream:
	 * 	{A,B,C}
	 * However, it may be indicated that the type is
	 * implicitly tagged in the caller, so it really boils down to the
	 *	{I,B,C} or even {I,C}
	 * This is because the implicit tag at above structure may replace 
	 * zero or more (or every) tags which follow it. We don't care
	 * about the precise number, as it is already computed for us
	 * by the ASN.1 compiler and placed into head->tags_impl_skip.
	 * So let's suppose the only tag left after implicit tagging is {I}.
	 * Yet, the table we have is {A,B,C} and head->tags_impl_skip=3.
	 * We need to check at least one tag in the loop, so the loop range
	 * is modified so it will be invoked at least one time.
	 */
	tagno = ctx->step	/* Continuing where left previously */
		+ (tag_mode==-1?(head->tags_impl_skip-1):0)
		+ (tag_mode==1?-1:0)
		;
	//assert(head->tags_count >= 1); ?May not be the case for CHOICE!
	assert(tagno < head->tags_count);	/* At least one loop */
	for((void)tagno; tagno < head->tags_count; tagno++, ctx->step++) {

		/*
		 * Fetch and process T from TLV.
		 */
		tag_len = ber_fetch_tag(ptr, size, &tlv_tag);
			ASN_DEBUG("Fetching tag from {%p,%ld} %02X: "
				"len %ld, tag %s",
				ptr, (long)size,
				*(uint8_t *)ptr, (long)tag_len,
				ber_tlv_tag_string(tlv_tag));
		switch(tag_len) {
		case -1: RETURN(RC_FAIL);
		case 0: RETURN(RC_WMORE);
		}

		tlv_constr = BER_TLV_CONSTRUCTED(ptr);

		/*
		 * If {I}, don't check anything.
		 * If {I,B,C}, check B and C unless we're at I.
		 */
		if(tag_mode != 0 && ctx->step == 0) {
			/*
			 * We don't expect tag to match here.
			 * It's just because we don't know how the tag
			 * is supposed to look like.
			 */
		} else {
		    assert(tagno >= 0);	/* Guaranteed by the code above */
		    if(tlv_tag != head->tags[tagno]) {
			/*
			 * Unexpected tag. Too bad.
			 */
		    	ASN_DEBUG("Expected: %s, expectation failed",
				ber_tlv_tag_string(head->tags[tagno]));
			RETURN(RC_FAIL);
		    }
		}

		/*
		 * Attention: if there are more tags expected,
		 * ensure that the current tag is presented
		 * in constructed form (it contains other tags!).
		 * If this one is the last one, check that the tag form
		 * matches the one given in descriptor.
		 */
		if(tagno < (head->tags_count - 1)) {
			if(tlv_constr == 0) {
				RETURN(RC_FAIL);
			}
		} else {
			if(head->last_tag_form != tlv_constr
			&& head->last_tag_form != -1) {
				RETURN(RC_FAIL);
			}
		}

		/*
		 * Fetch and process L from TLV.
		 */
		len_len = ber_fetch_length(tlv_constr,
			ptr + tag_len, size - tag_len, &tlv_len);
		switch(len_len) {
		case -1: RETURN(RC_FAIL);
		case 0: RETURN(RC_WMORE);
		}

		/*
		 * FIXME
		 * As of today, the chain of tags
		 * must either contain several indefinite length TLVs,
		 * or several definite length ones.
		 * No mixing is allowed.
		 */
		if(tlv_len == -1) {
			/*
			 * Indefinite length.
			 */
			if(limit_len == -1) {
				expect_00_terminators++;
			} else {
				ASN_DEBUG("Unexpected indefinite length "
					"in a chain of definite lengths");
				RETURN(RC_FAIL);
			}
			ADVANCE(tag_len + len_len);
			continue;
		} else {
			if(expect_00_terminators) {
				ASN_DEBUG("Unexpected definite length "
					"in a chain of indefinite lengths");
				RETURN(RC_FAIL);
			}
		}

		/*
		 * Check that multiple TLVs specify ever decreasing length,
		 * which is consistent.
		 */
		if(limit_len == -1) {
			limit_len    = tlv_len + tag_len + len_len;
		} else if(limit_len != tlv_len + tag_len + len_len) {
			/*
			 * Inner TLV specifies length which is inconsistent
			 * with the outer TLV's length value.
			 */
			ASN_DEBUG("Outer TLV is %d and inner is %d",
				limit_len, tlv_len);
			RETURN(RC_FAIL);
		}

		ADVANCE(tag_len + len_len);

		limit_len -= (tag_len + len_len);
		if((ssize_t)size > limit_len) {
			/*
			 * Make sure that we won't consume more bytes
			 * from the large buffer than the inferred limit.
			 */
			size = limit_len;
		}
	}

	if(opt_tlv_form)
		*opt_tlv_form = tlv_constr;
	if(expect_00_terminators)
		*last_length = -expect_00_terminators;
	else
		*last_length = tlv_len;

	RETURN(RC_OK);
}
