/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0 
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License. 
 */

#include "avro.h"
#include "avro_private.h"
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

char buf[4096];
avro_reader_t reader;
avro_writer_t writer;

typedef int (*avro_test) (void);

/*
 * Use a custom allocator that verifies that the size that we use to
 * free an object matches the size that we use to allocate it.
 */

static void *
test_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
{
	AVRO_UNUSED(ud);
	AVRO_UNUSED(osize);

	if (nsize == 0) {
		size_t  *size = ((size_t *) ptr) - 1;
		if (osize != *size) {
			fprintf(stderr,
				"Error freeing %p:\n"
				"Size passed to avro_free (%" PRIsz ") "
				"doesn't match size passed to "
				"avro_malloc (%" PRIsz ")\n",
				ptr, osize, *size);
			abort();
			//exit(EXIT_FAILURE);
		}
		free(size);
		return NULL;
	} else {
		size_t  real_size = nsize + sizeof(size_t);
		size_t  *old_size = ptr? ((size_t *) ptr)-1: NULL;
		size_t  *size = (size_t *) realloc(old_size, real_size);
		*size = nsize;
		return (size + 1);
	}
}

void init_rand(void)
{
	srand(time(NULL));
}

double rand_number(double from, double to)
{
	double range = to - from;
	return from + ((double)rand() / (RAND_MAX + 1.0)) * range;
}

int64_t rand_int64(void)
{
	return (int64_t) rand_number(LONG_MIN, LONG_MAX);
}

int32_t rand_int32(void)
{
	return (int32_t) rand_number(INT_MIN, INT_MAX);
}

void
write_read_check(avro_schema_t writers_schema, avro_datum_t datum,
		 avro_schema_t readers_schema, avro_datum_t expected, char *type)
{
	avro_datum_t datum_out;
	int validate;

	for (validate = 0; validate <= 1; validate++) {

		reader = avro_reader_memory(buf, sizeof(buf));
		writer = avro_writer_memory(buf, sizeof(buf));

		if (!expected) {
			expected = datum;
		}

		/* Validating read/write */
		if (avro_write_data
		    (writer, validate ? writers_schema : NULL, datum)) {
			fprintf(stderr, "Unable to write %s validate=%d\n  %s\n",
				type, validate, avro_strerror());
			exit(EXIT_FAILURE);
		}
		int64_t size =
		    avro_size_data(writer, validate ? writers_schema : NULL,
				   datum);
		if (size != avro_writer_tell(writer)) {
			fprintf(stderr,
				"Unable to calculate size %s validate=%d "
				"(%"PRId64" != %"PRId64")\n  %s\n",
				type, validate, size, avro_writer_tell(writer),
				avro_strerror());
			exit(EXIT_FAILURE);
		}
		if (avro_read_data
		    (reader, writers_schema, readers_schema, &datum_out)) {
			fprintf(stderr, "Unable to read %s validate=%d\n  %s\n",
				type, validate, avro_strerror());
			fprintf(stderr, "  %s\n", avro_strerror());
			exit(EXIT_FAILURE);
		}
		if (!avro_datum_equal(expected, datum_out)) {
			fprintf(stderr,
				"Unable to encode/decode %s validate=%d\n  %s\n",
				type, validate, avro_strerror());
			exit(EXIT_FAILURE);
		}

		avro_reader_dump(reader, stderr);
		avro_datum_decref(datum_out);
		avro_reader_free(reader);
		avro_writer_free(writer);
	}
}

static void test_json(avro_datum_t datum, const char *expected)
{
	char  *json = NULL;
	avro_datum_to_json(datum, 1, &json);
	if (strcmp(json, expected) != 0) {
		fprintf(stderr, "Unexpected JSON encoding: %s\n", json);
		exit(EXIT_FAILURE);
	}
	free(json);
}

static int test_string(void)
{
	unsigned int i;
	const char *strings[] = { "Four score and seven years ago",
		"our father brought forth on this continent",
		"a new nation", "conceived in Liberty",
		"and dedicated to the proposition that all men are created equal."
	};
	avro_schema_t writer_schema = avro_schema_string();
	for (i = 0; i < sizeof(strings) / sizeof(strings[0]); i++) {
		avro_datum_t datum = avro_givestring(strings[i], NULL);
		write_read_check(writer_schema, datum, NULL, NULL, "string");
		avro_datum_decref(datum);
	}

	avro_datum_t  datum = avro_givestring(strings[0], NULL);
	test_json(datum, "\"Four score and seven years ago\"");
	avro_datum_decref(datum);

	// The following should bork if we don't copy the string value
	// correctly (since we'll try to free a static string).

	datum = avro_string("this should be copied");
	avro_string_set(datum, "also this");
	avro_datum_decref(datum);

	avro_schema_decref(writer_schema);
	return 0;
}

static int test_bytes(void)
{
	char bytes[] = { 0xDE, 0xAD, 0xBE, 0xEF };
	avro_schema_t writer_schema = avro_schema_bytes();
	avro_datum_t datum;
	avro_datum_t expected_datum;

	datum = avro_givebytes(bytes, sizeof(bytes), NULL);
	write_read_check(writer_schema, datum, NULL, NULL, "bytes");
	test_json(datum, "\"\\u00de\\u00ad\\u00be\\u00ef\"");
	avro_datum_decref(datum);
	avro_schema_decref(writer_schema);

	datum = avro_givebytes(NULL, 0, NULL);
	avro_givebytes_set(datum, bytes, sizeof(bytes), NULL);
	expected_datum = avro_givebytes(bytes, sizeof(bytes), NULL);
	if (!avro_datum_equal(datum, expected_datum)) {
		fprintf(stderr,
		        "Expected equal bytes instances.\n");
		exit(EXIT_FAILURE);
	}
	avro_datum_decref(datum);
	avro_datum_decref(expected_datum);

	// The following should bork if we don't copy the bytes value
	// correctly (since we'll try to free a static string).

	datum = avro_bytes("original", 8);
	avro_bytes_set(datum, "alsothis", 8);
	avro_datum_decref(datum);

	avro_schema_decref(writer_schema);
	return 0;
}

static int test_int32(void)
{
	int i;
	avro_schema_t writer_schema = avro_schema_int();
	avro_schema_t long_schema = avro_schema_long();
	avro_schema_t float_schema = avro_schema_float();
	avro_schema_t double_schema = avro_schema_double();
	for (i = 0; i < 100; i++) {
		int32_t  value = rand_int32();
		avro_datum_t datum = avro_int32(value);
		avro_datum_t long_datum = avro_int64(value);
		avro_datum_t float_datum = avro_float(value);
		avro_datum_t double_datum = avro_double(value);
		write_read_check(writer_schema, datum, NULL, NULL, "int");
		write_read_check(writer_schema, datum,
				 long_schema, long_datum, "int->long");
		write_read_check(writer_schema, datum,
				 float_schema, float_datum, "int->float");
		write_read_check(writer_schema, datum,
				 double_schema, double_datum, "int->double");
		avro_datum_decref(datum);
		avro_datum_decref(long_datum);
		avro_datum_decref(float_datum);
		avro_datum_decref(double_datum);
	}

	avro_datum_t  datum = avro_int32(10000);
	test_json(datum, "10000");
	avro_datum_decref(datum);

	avro_schema_decref(writer_schema);
	avro_schema_decref(long_schema);
	avro_schema_decref(float_schema);
	avro_schema_decref(double_schema);
	return 0;
}

static int test_int64(void)
{
	int i;
	avro_schema_t writer_schema = avro_schema_long();
	avro_schema_t float_schema = avro_schema_float();
	avro_schema_t double_schema = avro_schema_double();
	for (i = 0; i < 100; i++) {
		int64_t  value = rand_int64();
		avro_datum_t datum = avro_int64(value);
		avro_datum_t float_datum = avro_float(value);
		avro_datum_t double_datum = avro_double(value);
		write_read_check(writer_schema, datum, NULL, NULL, "long");
		write_read_check(writer_schema, datum,
				 float_schema, float_datum, "long->float");
		write_read_check(writer_schema, datum,
				 double_schema, double_datum, "long->double");
		avro_datum_decref(datum);
		avro_datum_decref(float_datum);
		avro_datum_decref(double_datum);
	}

	avro_datum_t  datum = avro_int64(10000);
	test_json(datum, "10000");
	avro_datum_decref(datum);

	avro_schema_decref(writer_schema);
	avro_schema_decref(float_schema);
	avro_schema_decref(double_schema);
	return 0;
}

static int test_double(void)
{
	int i;
	avro_schema_t schema = avro_schema_double();
	for (i = 0; i < 100; i++) {
		avro_datum_t datum = avro_double(rand_number(-1.0E10, 1.0E10));
		write_read_check(schema, datum, NULL, NULL, "double");
		avro_datum_decref(datum);
	}

	avro_datum_t  datum = avro_double(2000.0);
	test_json(datum, "2000.0");
	avro_datum_decref(datum);

	avro_schema_decref(schema);
	return 0;
}

static int test_float(void)
{
	int i;
	avro_schema_t schema = avro_schema_float();
	avro_schema_t double_schema = avro_schema_double();
	for (i = 0; i < 100; i++) {
		float  value = rand_number(-1.0E10, 1.0E10);
		avro_datum_t datum = avro_float(value);
		avro_datum_t double_datum = avro_double(value);
		write_read_check(schema, datum, NULL, NULL, "float");
		write_read_check(schema, datum,
				 double_schema, double_datum, "float->double");
		avro_datum_decref(datum);
		avro_datum_decref(double_datum);
	}

	avro_datum_t  datum = avro_float(2000.0);
	test_json(datum, "2000.0");
	avro_datum_decref(datum);

	avro_schema_decref(schema);
	avro_schema_decref(double_schema);
	return 0;
}

static int test_boolean(void)
{
	int i;
	const char  *expected_json[] = { "false", "true" };
	avro_schema_t schema = avro_schema_boolean();
	for (i = 0; i <= 1; i++) {
		avro_datum_t datum = avro_boolean(i);
		write_read_check(schema, datum, NULL, NULL, "boolean");
		test_json(datum, expected_json[i]);
		avro_datum_decref(datum);
	}
	avro_schema_decref(schema);
	return 0;
}

static int test_null(void)
{
	avro_schema_t schema = avro_schema_null();
	avro_datum_t datum = avro_null();
	write_read_check(schema, datum, NULL, NULL, "null");
	test_json(datum, "null");
	avro_datum_decref(datum);
	return 0;
}

static int test_record(void)
{
	avro_schema_t schema = avro_schema_record("person", NULL);
	avro_schema_record_field_append(schema, "name", avro_schema_string());
	avro_schema_record_field_append(schema, "age", avro_schema_int());

	avro_datum_t datum = avro_record(schema);
	avro_datum_t name_datum, age_datum;

	name_datum = avro_givestring("Joseph Campbell", NULL);
	age_datum = avro_int32(83);

	avro_record_set(datum, "name", name_datum);
	avro_record_set(datum, "age", age_datum);

	write_read_check(schema, datum, NULL, NULL, "record");
	test_json(datum, "{\"name\": \"Joseph Campbell\", \"age\": 83}");

	int  rc;
	avro_record_set_field_value(rc, datum, int32, "age", 104);

	int32_t  age = 0;
	avro_record_get_field_value(rc, datum, int32, "age", &age);
	if (age != 104) {
		fprintf(stderr, "Incorrect age value\n");
		exit(EXIT_FAILURE);
	}

	avro_datum_decref(name_datum);
	avro_datum_decref(age_datum);
	avro_datum_decref(datum);
	avro_schema_decref(schema);
	return 0;
}

static int test_nested_record(void)
{
	const char  *json =
		"{"
		"  \"type\": \"record\","
		"  \"name\": \"list\","
		"  \"fields\": ["
		"    { \"name\": \"x\", \"type\": \"int\" },"
		"    { \"name\": \"y\", \"type\": \"int\" },"
		"    { \"name\": \"next\", \"type\": [\"null\",\"list\"]}"
		"  ]"
		"}";

	int  rval;

	avro_schema_t schema = NULL;
	avro_schema_error_t error;
	avro_schema_from_json(json, strlen(json), &schema, &error);

	avro_datum_t  head = avro_datum_from_schema(schema);
	avro_record_set_field_value(rval, head, int32, "x", 10);
	avro_record_set_field_value(rval, head, int32, "y", 10);

	avro_datum_t  next = NULL;
	avro_datum_t  tail = NULL;

	avro_record_get(head, "next", &next);
	avro_union_set_discriminant(next, 1, &tail);
	avro_record_set_field_value(rval, tail, int32, "x", 20);
	avro_record_set_field_value(rval, tail, int32, "y", 20);

	avro_record_get(tail, "next", &next);
	avro_union_set_discriminant(next, 0, NULL);

	write_read_check(schema, head, NULL, NULL, "nested record");

	avro_schema_decref(schema);
	avro_datum_decref(head);

	return 0;
}

static int test_enum(void)
{
	enum avro_languages {
		AVRO_C,
		AVRO_CPP,
		AVRO_PYTHON,
		AVRO_RUBY,
		AVRO_JAVA
	};
	avro_schema_t schema = avro_schema_enum("language");
	avro_datum_t datum = avro_enum(schema, AVRO_C);

	avro_schema_enum_symbol_append(schema, "C");
	avro_schema_enum_symbol_append(schema, "C++");
	avro_schema_enum_symbol_append(schema, "Python");
	avro_schema_enum_symbol_append(schema, "Ruby");
	avro_schema_enum_symbol_append(schema, "Java");

	if (avro_enum_get(datum) != AVRO_C) {
		fprintf(stderr, "Unexpected enum value AVRO_C\n");
		exit(EXIT_FAILURE);
	}

	if (strcmp(avro_enum_get_name(datum), "C") != 0) {
		fprintf(stderr, "Unexpected enum value name C\n");
		exit(EXIT_FAILURE);
	}

	write_read_check(schema, datum, NULL, NULL, "enum");
	test_json(datum, "\"C\"");

	avro_enum_set(datum, AVRO_CPP);
	if (strcmp(avro_enum_get_name(datum), "C++") != 0) {
		fprintf(stderr, "Unexpected enum value name C++\n");
		exit(EXIT_FAILURE);
	}

	write_read_check(schema, datum, NULL, NULL, "enum");
	test_json(datum, "\"C++\"");

	avro_enum_set_name(datum, "Python");
	if (avro_enum_get(datum) != AVRO_PYTHON) {
		fprintf(stderr, "Unexpected enum value AVRO_PYTHON\n");
		exit(EXIT_FAILURE);
	}

	write_read_check(schema, datum, NULL, NULL, "enum");
	test_json(datum, "\"Python\"");

	avro_datum_decref(datum);
	avro_schema_decref(schema);
	return 0;
}

static int test_array(void)
{
	int i, rval;
	avro_schema_t schema = avro_schema_array(avro_schema_int());
	avro_datum_t datum = avro_array(schema);

	for (i = 0; i < 10; i++) {
		avro_datum_t i32_datum = avro_int32(i);
		rval = avro_array_append_datum(datum, i32_datum);
		avro_datum_decref(i32_datum);
		if (rval) {
			exit(EXIT_FAILURE);
		}
	}

	if (avro_array_size(datum) != 10) {
		fprintf(stderr, "Unexpected array size");
		exit(EXIT_FAILURE);
	}

	write_read_check(schema, datum, NULL, NULL, "array");
	test_json(datum, "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
	avro_datum_decref(datum);
	avro_schema_decref(schema);
	return 0;
}

static int test_map(void)
{
	avro_schema_t schema = avro_schema_map(avro_schema_long());
	avro_datum_t datum = avro_map(schema);
	int64_t i = 0;
	char *nums[] =
	    { "zero", "one", "two", "three", "four", "five", "six", NULL };
	while (nums[i]) {
		avro_datum_t i_datum = avro_int64(i);
		avro_map_set(datum, nums[i], i_datum);
		avro_datum_decref(i_datum);
		i++;
	}

	if (avro_array_size(datum) != 7) {
		fprintf(stderr, "Unexpected map size\n");
		exit(EXIT_FAILURE);
	}

	avro_datum_t value;
	const char  *key;
	avro_map_get_key(datum, 2, &key);
	avro_map_get(datum, key, &value);
	int64_t  val;
	avro_int64_get(value, &val);

	if (val != 2) {
		fprintf(stderr, "Unexpected map value 2\n");
		exit(EXIT_FAILURE);
	}

	int  index;
	if (avro_map_get_index(datum, "two", &index)) {
		fprintf(stderr, "Can't get index for key \"two\": %s\n",
			avro_strerror());
		exit(EXIT_FAILURE);
	}
	if (index != 2) {
		fprintf(stderr, "Unexpected index for key \"two\"\n");
		exit(EXIT_FAILURE);
	}
	if (!avro_map_get_index(datum, "foobar", &index)) {
		fprintf(stderr, "Unexpected index for key \"foobar\"\n");
		exit(EXIT_FAILURE);
	}

	write_read_check(schema, datum, NULL, NULL, "map");
	test_json(datum,
		  "{\"zero\": 0, \"one\": 1, \"two\": 2, \"three\": 3, "
		  "\"four\": 4, \"five\": 5, \"six\": 6}");
	avro_datum_decref(datum);
	avro_schema_decref(schema);
	return 0;
}

static int test_union(void)
{
	avro_schema_t schema = avro_schema_union();
	avro_datum_t union_datum;
	avro_datum_t datum;
	avro_datum_t union_datum1;
	avro_datum_t datum1;

	avro_schema_union_append(schema, avro_schema_string());
	avro_schema_union_append(schema, avro_schema_int());
	avro_schema_union_append(schema, avro_schema_null());

	datum = avro_givestring("Follow your bliss.", NULL);
	union_datum = avro_union(schema, 0, datum);

	if (avro_union_discriminant(union_datum) != 0) {
		fprintf(stderr, "Unexpected union discriminant\n");
		exit(EXIT_FAILURE);
	}

	if (avro_union_current_branch(union_datum) != datum) {
		fprintf(stderr, "Unexpected union branch datum\n");
		exit(EXIT_FAILURE);
	}

	union_datum1 = avro_datum_from_schema(schema);
	avro_union_set_discriminant(union_datum1, 0, &datum1);
	avro_givestring_set(datum1, "Follow your bliss.", NULL);

	if (!avro_datum_equal(datum, datum1)) {
		fprintf(stderr, "Union values should be equal\n");
		exit(EXIT_FAILURE);
	}

	write_read_check(schema, union_datum, NULL, NULL, "union");
	test_json(union_datum, "{\"string\": \"Follow your bliss.\"}");

	avro_datum_decref(datum);
	avro_union_set_discriminant(union_datum, 2, &datum);
	test_json(union_datum, "null");

	avro_datum_decref(union_datum);
	avro_datum_decref(datum);
	avro_datum_decref(union_datum1);
	avro_schema_decref(schema);
	return 0;
}

static int test_fixed(void)
{
	char bytes[] = { 0xD, 0xA, 0xD, 0xA, 0xB, 0xA, 0xB, 0xA };
	avro_schema_t schema = avro_schema_fixed("msg", sizeof(bytes));
	avro_datum_t datum;
	avro_datum_t expected_datum;

	datum = avro_givefixed(schema, bytes, sizeof(bytes), NULL);
	write_read_check(schema, datum, NULL, NULL, "fixed");
	test_json(datum, "\"\\r\\n\\r\\n\\u000b\\n\\u000b\\n\"");
	avro_datum_decref(datum);

	datum = avro_givefixed(schema, NULL, sizeof(bytes), NULL);
	avro_givefixed_set(datum, bytes, sizeof(bytes), NULL);
	expected_datum = avro_givefixed(schema, bytes, sizeof(bytes), NULL);
	if (!avro_datum_equal(datum, expected_datum)) {
		fprintf(stderr,
		        "Expected equal fixed instances.\n");
		exit(EXIT_FAILURE);
	}
	avro_datum_decref(datum);
	avro_datum_decref(expected_datum);

	// The following should bork if we don't copy the fixed value
	// correctly (since we'll try to free a static string).

	datum = avro_fixed(schema, "original", 8);
	avro_fixed_set(datum, "alsothis", 8);
	avro_datum_decref(datum);

	avro_schema_decref(schema);
	return 0;
}

int main(void)
{
	avro_set_allocator(test_allocator, NULL);

	unsigned int i;
	struct avro_tests {
		char *name;
		avro_test func;
	} tests[] = {
		{
		"string", test_string}, {
		"bytes", test_bytes}, {
		"int", test_int32}, {
		"long", test_int64}, {
		"float", test_float}, {
		"double", test_double}, {
		"boolean", test_boolean}, {
		"null", test_null}, {
		"record", test_record}, {
		"nested_record", test_nested_record}, {
		"enum", test_enum}, {
		"array", test_array}, {
		"map", test_map}, {
		"fixed", test_fixed}, {
		"union", test_union}
	};

	init_rand();
	for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
		struct avro_tests *test = tests + i;
		fprintf(stderr, "**** Running %s tests ****\n", test->name);
		if (test->func() != 0) {
			return EXIT_FAILURE;
		}
	}
	return EXIT_SUCCESS;
}
