/*
 * 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 <errno.h>
#include <stdlib.h>
#include <string.h>

#include "avro/allocation.h"
#include "avro/data.h"
#include "avro/errors.h"
#include "avro/value.h"
#include "avro_private.h"


#define check_return(retval, call) \
	do { \
		int  rval = call; \
		if (rval != 0) { return (retval); } \
	} while (0)


void
avro_value_incref(avro_value_t *value)
{
	value->iface->incref(value);
}

void
avro_value_decref(avro_value_t *value)
{
	value->iface->decref(value);
	avro_value_iface_decref(value->iface);
	value->iface = NULL;
	value->self = NULL;
}

void
avro_value_copy_ref(avro_value_t *dest, const avro_value_t *src)
{
	dest->iface = src->iface;
	dest->self = src->self;
	avro_value_iface_incref(dest->iface);
	dest->iface->incref(dest);
}

void
avro_value_move_ref(avro_value_t *dest, avro_value_t *src)
{
	dest->iface = src->iface;
	dest->self = src->self;
	src->iface = NULL;
	src->self = NULL;
}


int
avro_value_equal_fast(avro_value_t *val1, avro_value_t *val2)
{
	avro_type_t  type1 = avro_value_get_type(val1);
	avro_type_t  type2 = avro_value_get_type(val2);
	if (type1 != type2) {
		return 0;
	}

	switch (type1) {
		case AVRO_BOOLEAN:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_boolean(val1, &v1));
			check_return(0, avro_value_get_boolean(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_BYTES:
		{
			const void  *buf1;
			const void  *buf2;
			size_t  size1;
			size_t  size2;
			check_return(0, avro_value_get_bytes(val1, &buf1, &size1));
			check_return(0, avro_value_get_bytes(val2, &buf2, &size2));
			if (size1 != size2) {
				return 0;
			}
			return (memcmp(buf1, buf2, size1) == 0);
		}

		case AVRO_DOUBLE:
		{
			double  v1;
			double  v2;
			check_return(0, avro_value_get_double(val1, &v1));
			check_return(0, avro_value_get_double(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_FLOAT:
		{
			float  v1;
			float  v2;
			check_return(0, avro_value_get_float(val1, &v1));
			check_return(0, avro_value_get_float(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_INT32:
		{
			int32_t  v1;
			int32_t  v2;
			check_return(0, avro_value_get_int(val1, &v1));
			check_return(0, avro_value_get_int(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_INT64:
		{
			int64_t  v1;
			int64_t  v2;
			check_return(0, avro_value_get_long(val1, &v1));
			check_return(0, avro_value_get_long(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_NULL:
		{
			check_return(0, avro_value_get_null(val1));
			check_return(0, avro_value_get_null(val2));
			return 1;
		}

		case AVRO_STRING:
		{
			const char  *buf1;
			const char  *buf2;
			size_t  size1;
			size_t  size2;
			check_return(0, avro_value_get_string(val1, &buf1, &size1));
			check_return(0, avro_value_get_string(val2, &buf2, &size2));
			if (size1 != size2) {
				return 0;
			}
			return (memcmp(buf1, buf2, size1) == 0);
		}

		case AVRO_ARRAY:
		{
			size_t  count1;
			size_t  count2;
			check_return(0, avro_value_get_size(val1, &count1));
			check_return(0, avro_value_get_size(val2, &count2));
			if (count1 != count2) {
				return 0;
			}

			size_t  i;
			for (i = 0; i < count1; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				if (!avro_value_equal_fast(&child1, &child2)) {
					return 0;
				}
			}

			return 1;
		}

		case AVRO_ENUM:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_enum(val1, &v1));
			check_return(0, avro_value_get_enum(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_FIXED:
		{
			const void  *buf1;
			const void  *buf2;
			size_t  size1;
			size_t  size2;
			check_return(0, avro_value_get_fixed(val1, &buf1, &size1));
			check_return(0, avro_value_get_fixed(val2, &buf2, &size2));
			if (size1 != size2) {
				return 0;
			}
			return (memcmp(buf1, buf2, size1) == 0);
		}

		case AVRO_MAP:
		{
			size_t  count1;
			size_t  count2;
			check_return(0, avro_value_get_size(val1, &count1));
			check_return(0, avro_value_get_size(val2, &count2));
			if (count1 != count2) {
				return 0;
			}

			size_t  i;
			for (i = 0; i < count1; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				const char  *key1;
				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, &key1));
				check_return(0, avro_value_get_by_name
					     (val2, key1, &child2, NULL));
				if (!avro_value_equal_fast(&child1, &child2)) {
					return 0;
				}
			}

			return 1;
		}

		case AVRO_RECORD:
		{
			size_t  count1;
			check_return(0, avro_value_get_size(val1, &count1));

			size_t  i;
			for (i = 0; i < count1; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				if (!avro_value_equal_fast(&child1, &child2)) {
					return 0;
				}
			}

			return 1;
		}

		case AVRO_UNION:
		{
			int  disc1;
			int  disc2;
			check_return(0, avro_value_get_discriminant(val1, &disc1));
			check_return(0, avro_value_get_discriminant(val2, &disc2));
			if (disc1 != disc2) {
				return 0;
			}

			avro_value_t  branch1;
			avro_value_t  branch2;
			check_return(0, avro_value_get_current_branch(val1, &branch1));
			check_return(0, avro_value_get_current_branch(val2, &branch2));
			return avro_value_equal_fast(&branch1, &branch2);
		}

		default:
			return 0;
	}
}

int
avro_value_equal(avro_value_t *val1, avro_value_t *val2)
{
	avro_schema_t  schema1 = avro_value_get_schema(val1);
	avro_schema_t  schema2 = avro_value_get_schema(val2);
	if (!avro_schema_equal(schema1, schema2)) {
		return 0;
	}

	return avro_value_equal_fast(val1, val2);
}


#define cmp(v1, v2) \
	(((v1) == (v2))? 0: \
	 ((v1) <  (v2))? -1: 1)
int
avro_value_cmp_fast(avro_value_t *val1, avro_value_t *val2)
{
	avro_type_t  type1 = avro_value_get_type(val1);
	avro_type_t  type2 = avro_value_get_type(val2);
	if (type1 != type2) {
		return -1;
	}

	switch (type1) {
		case AVRO_BOOLEAN:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_boolean(val1, &v1));
			check_return(0, avro_value_get_boolean(val2, &v2));
			return cmp(!!v1, !!v2);
		}

		case AVRO_BYTES:
		{
			const void  *buf1;
			const void  *buf2;
			size_t  size1;
			size_t  size2;
			size_t  min_size;
			int  result;

			check_return(0, avro_value_get_bytes(val1, &buf1, &size1));
			check_return(0, avro_value_get_bytes(val2, &buf2, &size2));

			min_size = (size1 < size2)? size1: size2;
			result = memcmp(buf1, buf2, min_size);
			if (result != 0) {
				return result;
			} else {
				return cmp(size1, size2);
			}
		}

		case AVRO_DOUBLE:
		{
			double  v1;
			double  v2;
			check_return(0, avro_value_get_double(val1, &v1));
			check_return(0, avro_value_get_double(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_FLOAT:
		{
			float  v1;
			float  v2;
			check_return(0, avro_value_get_float(val1, &v1));
			check_return(0, avro_value_get_float(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_INT32:
		{
			int32_t  v1;
			int32_t  v2;
			check_return(0, avro_value_get_int(val1, &v1));
			check_return(0, avro_value_get_int(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_INT64:
		{
			int64_t  v1;
			int64_t  v2;
			check_return(0, avro_value_get_long(val1, &v1));
			check_return(0, avro_value_get_long(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_NULL:
		{
			check_return(0, avro_value_get_null(val1));
			check_return(0, avro_value_get_null(val2));
			return 0;
		}

		case AVRO_STRING:
		{
			const char  *buf1;
			const char  *buf2;
			size_t  size1;
			size_t  size2;
			size_t  min_size;
			int  result;
			check_return(0, avro_value_get_string(val1, &buf1, &size1));
			check_return(0, avro_value_get_string(val2, &buf2, &size2));

			min_size = (size1 < size2)? size1: size2;
			result = memcmp(buf1, buf2, min_size);
			if (result != 0) {
				return result;
			} else {
				return cmp(size1, size2);
			}
		}

		case AVRO_ARRAY:
		{
			size_t  count1;
			size_t  count2;
			size_t  min_count;
			size_t  i;
			check_return(0, avro_value_get_size(val1, &count1));
			check_return(0, avro_value_get_size(val2, &count2));

			min_count = (count1 < count2)? count1: count2;
			for (i = 0; i < min_count; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				int  result;
				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				result = avro_value_cmp_fast(&child1, &child2);
				if (result != 0) {
					return result;
				}
			}

			return cmp(count1, count2);
		}

		case AVRO_ENUM:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_enum(val1, &v1));
			check_return(0, avro_value_get_enum(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_FIXED:
		{
			const void  *buf1;
			const void  *buf2;
			size_t  size1;
			size_t  size2;
			check_return(0, avro_value_get_fixed(val1, &buf1, &size1));
			check_return(0, avro_value_get_fixed(val2, &buf2, &size2));
			if (size1 != size2) {
				return -1;
			}
			return memcmp(buf1, buf2, size1);
		}

		case AVRO_MAP:
		{
			return -1;
		}

		case AVRO_RECORD:
		{
			size_t  count1;
			check_return(0, avro_value_get_size(val1, &count1));

			size_t  i;
			for (i = 0; i < count1; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				int  result;

				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				result = avro_value_cmp_fast(&child1, &child2);
				if (result != 0) {
					return result;
				}
			}

			return 0;
		}

		case AVRO_UNION:
		{
			int  disc1;
			int  disc2;
			check_return(0, avro_value_get_discriminant(val1, &disc1));
			check_return(0, avro_value_get_discriminant(val2, &disc2));

			if (disc1 == disc2) {
				avro_value_t  branch1;
				avro_value_t  branch2;
				check_return(0, avro_value_get_current_branch(val1, &branch1));
				check_return(0, avro_value_get_current_branch(val2, &branch2));
				return avro_value_cmp_fast(&branch1, &branch2);
			} else {
				return cmp(disc1, disc2);
			}
		}

		default:
			return 0;
	}
}

int
avro_value_cmp(avro_value_t *val1, avro_value_t *val2)
{
	avro_schema_t  schema1 = avro_value_get_schema(val1);
	avro_schema_t  schema2 = avro_value_get_schema(val2);
	if (!avro_schema_equal(schema1, schema2)) {
		return 0;
	}

	return avro_value_cmp_fast(val1, val2);
}


int
avro_value_copy_fast(avro_value_t *dest, const avro_value_t *src)
{
	avro_type_t  dest_type = avro_value_get_type(dest);
	avro_type_t  src_type = avro_value_get_type(src);
	if (dest_type != src_type) {
		return 0;
	}

	int  rval;
	check(rval, avro_value_reset(dest));

	switch (dest_type) {
		case AVRO_BOOLEAN:
		{
			int  val;
			check(rval, avro_value_get_boolean(src, &val));
			return avro_value_set_boolean(dest, val);
		}

		case AVRO_BYTES:
		{
			avro_wrapped_buffer_t  val;
			check(rval, avro_value_grab_bytes(src, &val));
			return avro_value_give_bytes(dest, &val);
		}

		case AVRO_DOUBLE:
		{
			double  val;
			check(rval, avro_value_get_double(src, &val));
			return avro_value_set_double(dest, val);
		}

		case AVRO_FLOAT:
		{
			float  val;
			check(rval, avro_value_get_float(src, &val));
			return avro_value_set_float(dest, val);
		}

		case AVRO_INT32:
		{
			int32_t  val;
			check(rval, avro_value_get_int(src, &val));
			return avro_value_set_int(dest, val);
		}

		case AVRO_INT64:
		{
			int64_t  val;
			check(rval, avro_value_get_long(src, &val));
			return avro_value_set_long(dest, val);
		}

		case AVRO_NULL:
		{
			check(rval, avro_value_get_null(src));
			return avro_value_set_null(dest);
		}

		case AVRO_STRING:
		{
			avro_wrapped_buffer_t  val;
			check(rval, avro_value_grab_string(src, &val));
			return avro_value_give_string_len(dest, &val);
		}

		case AVRO_ARRAY:
		{
			size_t  count;
			check(rval, avro_value_get_size(src, &count));

			size_t  i;
			for (i = 0; i < count; i++) {
				avro_value_t  src_child;
				avro_value_t  dest_child;

				check(rval, avro_value_get_by_index
				      (src, i, &src_child, NULL));
				check(rval, avro_value_append
				      (dest, &dest_child, NULL));
				check(rval, avro_value_copy_fast
				      (&dest_child, &src_child));
			}

			return 0;
		}

		case AVRO_ENUM:
		{
			int  val;
			check(rval, avro_value_get_enum(src, &val));
			return avro_value_set_enum(dest, val);
		}

		case AVRO_FIXED:
		{
			avro_wrapped_buffer_t  val;
			check(rval, avro_value_grab_fixed(src, &val));
			return avro_value_give_fixed(dest, &val);
		}

		case AVRO_MAP:
		{
			size_t  count;
			check(rval, avro_value_get_size(src, &count));

			size_t  i;
			for (i = 0; i < count; i++) {
				avro_value_t  src_child;
				avro_value_t  dest_child;
				const char  *key;

				check(rval, avro_value_get_by_index
				      (src, i, &src_child, &key));
				check(rval, avro_value_add
				      (dest, key, &dest_child, NULL, NULL));
				check(rval, avro_value_copy_fast
				      (&dest_child, &src_child));
			}

			return 0;
		}

		case AVRO_RECORD:
		{
			size_t  count;
			check(rval, avro_value_get_size(src, &count));

			size_t  i;
			for (i = 0; i < count; i++) {
				avro_value_t  src_child;
				avro_value_t  dest_child;

				check(rval, avro_value_get_by_index
				      (src, i, &src_child, NULL));
				check(rval, avro_value_get_by_index
				      (dest, i, &dest_child, NULL));
				check(rval, avro_value_copy_fast
				      (&dest_child, &src_child));
			}

			return 0;
		}

		case AVRO_UNION:
		{
			int  disc;
			check(rval, avro_value_get_discriminant(src, &disc));

			avro_value_t  src_branch;
			avro_value_t  dest_branch;

			check(rval, avro_value_get_current_branch(src, &src_branch));
			check(rval, avro_value_set_branch(dest, disc, &dest_branch));

			return avro_value_copy_fast(&dest_branch, &src_branch);
		}

		default:
			return 0;
	}
}


int
avro_value_copy(avro_value_t *dest, const avro_value_t *src)
{
	avro_schema_t  dest_schema = avro_value_get_schema(dest);
	avro_schema_t  src_schema = avro_value_get_schema(src);
	if (!avro_schema_equal(dest_schema, src_schema)) {
		avro_set_error("Schemas don't match");
		return EINVAL;
	}

	return avro_value_copy_fast(dest, src);
}
