#undef	NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#include <T1.h>
#include <T2.h>

static unsigned char buf[4096];
static int buf_offset;

static int
_buf_writer(const void *buffer, size_t size, void *app_key) {
	unsigned char *b, *bend;
	(void)app_key;
	assert(buf_offset + size < sizeof(buf));
	memcpy(buf + buf_offset, buffer, size);
	b = buf + buf_offset;
	bend = b + size;
	printf("=> [");
	for(; b < bend; b++)
		printf(" %02X", *b);
	printf("]:%ld\n", (long)size);
	buf_offset += size;
	return 0;
}

static int
save_object(void *bs, asn_TYPE_descriptor_t *td) {
	asn_enc_rval_t rval; /* Return value */
	int i;

	buf_offset = 0;
	
	rval = der_encode(td, bs, _buf_writer, 0);
	if (rval.encoded == -1) {
		fprintf(stderr,
			"Cannot encode %s: %s\n",
			rval.failed_type->name, strerror(errno));
		assert(rval.encoded != -1);
		return -1;	/* JIC */
	}

	buf[buf_offset++] = 0xab;	/* Finalize with garbage */

	asn_fprint(stderr, td, bs);

	printf("OUT: [");
	for(i = 0; i < buf_offset; i++)
		printf(" %02x", buf[i]);
	printf("]\n");

	return 0;
}

static int
load_object(void *bs, asn_TYPE_descriptor_t *td) {
	asn_dec_rval_t rval;

	fprintf(stderr, "\nLOADING OBJECT OF SIZE %d\n", buf_offset);

	rval = ber_decode(0, td, (void **)&bs, buf, buf_offset);
	assert(rval.code == RC_OK);

	asn_fprint(stderr, td, bs);

	return (rval.code == RC_OK)?0:-1;
}

/* [3] IMPLICIT SEQUENCE { b BOOLEAN } */
uint8_t test_any_buf1[] = { 0xa3, 0x80, /* [3], constructed, indefinite */
	0x01, 0x01, 0xff,	/* b BOOLEAN ::= TRUE */
	0x00, 0x00 /* End of content octets */ };

/* b BOOLEAN */
uint8_t test_any_buf2[] = { 0x01, 0x01, 0x13 };

int
main() {
	asn_TYPE_descriptor_t *td1 = &asn_DEF_T1;
	asn_TYPE_descriptor_t *td2 = &asn_DEF_T2;
	T1_t t1, t1_new;
	T2_t t2, t2_new;
	int ret;

	/*
	 * Test the T1 with constructed indefinite length ANY encoding.
	 */
	memset(&t1, 0, sizeof(t1));
	memset(&t1_new, 0, sizeof(t1_new));

	t1.i = 112233;
	t1.any.buf = test_any_buf1;
	t1.any.size = sizeof(test_any_buf1);

	/* Save->Load must succeed */
	save_object(&t1, td1);
	ret = load_object(&t1_new, td1);

	assert(ret == 0);
	assert(t1_new.i == 112233);
	assert(t1_new.any.size == sizeof(test_any_buf1));
	assert(memcmp(t1_new.any.buf, test_any_buf1, sizeof(test_any_buf1)) == 0);

	/*
	 * Test the T1 with primitive encoding.
	 */
	memset(&t1, 0, sizeof(t1));
	memset(&t1_new, 0, sizeof(t1_new));

	t1.i = -112233;
	t1.any.buf = test_any_buf2;
	t1.any.size = sizeof(test_any_buf2);

	/* Save->Load must succeed */
	save_object(&t1, td1);
	ret = load_object(&t1_new, td1);

	assert(ret == 0);
	assert(t1_new.i == -112233);
	assert(t1_new.any.size == sizeof(test_any_buf2));
	assert(memcmp(t1_new.any.buf, test_any_buf2, sizeof(test_any_buf2)) == 0);

	/*
	 * Test the T2 empty sequence.
	 */
	memset(&t2, 0, sizeof(t2));
	memset(&t2_new, 0, sizeof(t2_new));

	t2.i = 332211;
	t2.any = calloc(1, sizeof(*t2.any));
	t2.any->buf = 0;
	t2.any->size = 0;

	/* Save->Load must succeed */
	save_object(&t2, td2);
	ret = load_object(&t2_new, td2);

	assert(ret == 0);
	assert(t2_new.i == 332211);
	assert(t2_new.any->size == 0);

	/*
	 * Test the T2 sequence.
	 */
	memset(&t2, 0, sizeof(t2));
	memset(&t2_new, 0, sizeof(t2_new));

	t2.i = 332211;
	t2.any = calloc(1, sizeof(*t2.any));
	t2.any->buf = test_any_buf1;
	t2.any->size = sizeof(test_any_buf1);

	/* Save->Load must succeed */
	save_object(&t2, td2);
	ret = load_object(&t2_new, td2);

	assert(ret == 0);
	assert(t2_new.i == 332211);
	assert(t2_new.any->size == sizeof(test_any_buf1));
	assert(memcmp(t2_new.any->buf, test_any_buf1, sizeof(test_any_buf1)) == 0);

	/*
	 * Test the T2 sequence with primitive encoding.
	 */
	memset(&t2, 0, sizeof(t2));
	memset(&t2_new, 0, sizeof(t2_new));

	t2.i = 0;
	t2.any = calloc(1, sizeof(*t2.any));
	t2.any->buf = test_any_buf2;
	t2.any->size = sizeof(test_any_buf2);

	/* Save->Load must succeed */
	save_object(&t2, td2);
	ret = load_object(&t2_new, td2);

	assert(ret == 0);
	assert(t2_new.i == 0);
	assert(t2_new.any->size == sizeof(test_any_buf2));
	assert(memcmp(t2_new.any->buf, test_any_buf2, sizeof(test_any_buf2)) == 0);

	/*
	 * Test T2 with ANY element omitted.
	 */
	free(t2.any);
	t2.any = 0;
	memset(&t2_new, 0, sizeof(t2_new));

	save_object(&t2, td2);
	ret = load_object(&t2_new, td2);

	assert(ret == 0);
	assert(t2_new.i == 0);
	assert(t2_new.any == 0);

	printf("OK\n");

	return ret;
}
