/*
 * 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 <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <avro/platform.h>
#include <avro/platform.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "avro.h"
#include "avro_private.h"


/* The path separator to use in the JSON output. */

static const char  *separator = "/";


/*-- PROCESSING A FILE --*/

/**
 * Fills in a raw string with the path to an element of an array.
 */

static void
create_array_prefix(avro_raw_string_t *dest, const char *prefix, size_t index)
{
	static char  buf[100];
	snprintf(buf, sizeof(buf), "%" PRIsz, index);
	avro_raw_string_set(dest, prefix);
	avro_raw_string_append(dest, separator);
	avro_raw_string_append(dest, buf);
}

static void
create_object_prefix(avro_raw_string_t *dest, const char *prefix, const char *key)
{
	/*
	 * Make sure that the key doesn't contain the separator
	 * character.
	 */

	if (strstr(key, separator) != NULL) {
		fprintf(stderr,
			"Error: Element \"%s\" in object %s "
			"contains the separator character.\n"
			"Please use the --separator option to choose another.\n",
			key, prefix);
		exit(1);
	}

	avro_raw_string_set(dest, prefix);
	avro_raw_string_append(dest, separator);
	avro_raw_string_append(dest, key);
}

static void
print_bytes_value(const char *buf, size_t size)
{
	size_t  i;
	printf("\"");
	for (i = 0; i < size; i++)
	{
		if (buf[i] == '"') {
			printf("\\\"");
		} else if (buf[i] == '\\') {
			printf("\\\\");
		} else if (buf[i] == '\b') {
			printf("\\b");
		} else if (buf[i] == '\f') {
			printf("\\f");
		} else if (buf[i] == '\n') {
			printf("\\n");
		} else if (buf[i] == '\r') {
			printf("\\r");
		} else if (buf[i] == '\t') {
			printf("\\t");
		} else if (isprint(buf[i])) {
			printf("%c", (int) buf[i]);
		} else {
			printf("\\u00%02x", (unsigned int) (unsigned char) buf[i]);
		}
	}
	printf("\"");
}

static void
process_value(const char *prefix, avro_value_t *value);

static void
process_array(const char *prefix, avro_value_t *value)
{
	printf("%s\t[]\n", prefix);
	size_t  element_count;
	avro_value_get_size(value, &element_count);

	avro_raw_string_t  element_prefix;
	avro_raw_string_init(&element_prefix);

	size_t  i;
	for (i = 0; i < element_count; i++) {
		avro_value_t  element_value;
		avro_value_get_by_index(value, i, &element_value, NULL);

		create_array_prefix(&element_prefix, prefix, i);
		process_value((const char *) avro_raw_string_get(&element_prefix), &element_value);
	}

	avro_raw_string_done(&element_prefix);
}

static void
process_enum(const char *prefix, avro_value_t *value)
{
	int  val;
	const char  *symbol_name;

	avro_schema_t  schema = avro_value_get_schema(value);
	avro_value_get_enum(value, &val);
	symbol_name = avro_schema_enum_get(schema, val);
	printf("%s\t", prefix);
	print_bytes_value(symbol_name, strlen(symbol_name));
	printf("\n");
}

static void
process_map(const char *prefix, avro_value_t *value)
{
	printf("%s\t{}\n", prefix);
	size_t  element_count;
	avro_value_get_size(value, &element_count);

	avro_raw_string_t  element_prefix;
	avro_raw_string_init(&element_prefix);

	size_t  i;
	for (i = 0; i < element_count; i++) {
		const char  *key;
		avro_value_t  element_value;
		avro_value_get_by_index(value, i, &element_value, &key);

		create_object_prefix(&element_prefix, prefix, key);
		process_value((const char *) avro_raw_string_get(&element_prefix), &element_value);
	}

	avro_raw_string_done(&element_prefix);
}

static void
process_record(const char *prefix, avro_value_t *value)
{
	printf("%s\t{}\n", prefix);
	size_t  field_count;
	avro_value_get_size(value, &field_count);

	avro_raw_string_t  field_prefix;
	avro_raw_string_init(&field_prefix);

	size_t  i;
	for (i = 0; i < field_count; i++) {
		avro_value_t  field_value;
		const char  *field_name;
		avro_value_get_by_index(value, i, &field_value, &field_name);

		create_object_prefix(&field_prefix, prefix, field_name);
		process_value((const char *) avro_raw_string_get(&field_prefix), &field_value);
	}

	avro_raw_string_done(&field_prefix);
}

static void
process_union(const char *prefix, avro_value_t *value)
{
	avro_value_t  branch_value;
	avro_value_get_current_branch(value, &branch_value);

	/* nulls in a union aren't wrapped in a JSON object */
	if (avro_value_get_type(&branch_value) == AVRO_NULL) {
		printf("%s\tnull\n", prefix);
		return;
	}

	int  discriminant;
	avro_value_get_discriminant(value, &discriminant);

	avro_schema_t  schema = avro_value_get_schema(value);
	avro_schema_t  branch_schema = avro_schema_union_branch(schema, discriminant);
	const char  *branch_name = avro_schema_type_name(branch_schema);

	avro_raw_string_t  branch_prefix;
	avro_raw_string_init(&branch_prefix);
	create_object_prefix(&branch_prefix, prefix, branch_name);

	printf("%s\t{}\n", prefix);
	process_value((const char *) avro_raw_string_get(&branch_prefix), &branch_value);

	avro_raw_string_done(&branch_prefix);
}

static void
process_value(const char *prefix, avro_value_t *value)
{
	avro_type_t  type = avro_value_get_type(value);
	switch (type) {
		case AVRO_BOOLEAN:
		{
			int  val;
			avro_value_get_boolean(value, &val);
			printf("%s\t%s\n", prefix, val? "true": "false");
			return;
		}

		case AVRO_BYTES:
		{
			const void  *buf;
			size_t  size;
			avro_value_get_bytes(value, &buf, &size);
			printf("%s\t", prefix);
			print_bytes_value((const char *) buf, size);
			printf("\n");
			return;
		}

		case AVRO_DOUBLE:
		{
			double  val;
			avro_value_get_double(value, &val);
			printf("%s\t%lf\n", prefix, val);
			return;
		}

		case AVRO_FLOAT:
		{
			float  val;
			avro_value_get_float(value, &val);
			printf("%s\t%f\n", prefix, val);
			return;
		}

		case AVRO_INT32:
		{
			int32_t  val;
			avro_value_get_int(value, &val);
			printf("%s\t%" PRId32 "\n", prefix, val);
			return;
		}

		case AVRO_INT64:
		{
			int64_t  val;
			avro_value_get_long(value, &val);
			printf("%s\t%" PRId64 "\n", prefix, val);
			return;
		}

		case AVRO_NULL:
		{
			avro_value_get_null(value);
			printf("%s\tnull\n", prefix);
			return;
		}

		case AVRO_STRING:
		{
			/* TODO: Convert the UTF-8 to the current
			 * locale's character set */
			const char  *buf;
			size_t  size;
			avro_value_get_string(value, &buf, &size);
			printf("%s\t", prefix);
                        /* For strings, size includes the NUL terminator. */
			print_bytes_value(buf, size-1);
			printf("\n");
			return;
		}

		case AVRO_ARRAY:
			process_array(prefix, value);
			return;

		case AVRO_ENUM:
			process_enum(prefix, value);
			return;

		case AVRO_FIXED:
		{
			const void  *buf;
			size_t  size;
			avro_value_get_fixed(value, &buf, &size);
			printf("%s\t", prefix);
			print_bytes_value((const char *) buf, size);
			printf("\n");
			return;
		}

		case AVRO_MAP:
			process_map(prefix, value);
			return;

		case AVRO_RECORD:
			process_record(prefix, value);
			return;

		case AVRO_UNION:
			process_union(prefix, value);
			return;

		default:
		{
			fprintf(stderr, "Unknown schema type\n");
			exit(1);
		}
	}
}

static void
process_file(const char *filename)
{
	avro_file_reader_t  reader;

	if (filename == NULL) {
		if (avro_file_reader_fp(stdin, "<stdin>", 0, &reader)) {
			fprintf(stderr, "Error opening <stdin>:\n  %s\n",
				avro_strerror());
			exit(1);
		}
	} else {
		if (avro_file_reader(filename, &reader)) {
			fprintf(stderr, "Error opening %s:\n  %s\n",
				filename, avro_strerror());
			exit(1);
		}
	}

	/* The JSON root is an array */
	printf("%s\t[]\n", separator);

	avro_raw_string_t  prefix;
	avro_raw_string_init(&prefix);

	avro_schema_t  wschema = avro_file_reader_get_writer_schema(reader);
	avro_value_iface_t  *iface = avro_generic_class_from_schema(wschema);
	avro_value_t  value;
	avro_generic_value_new(iface, &value);

	size_t  record_number = 0;
	int rval;

	for (; (rval = avro_file_reader_read_value(reader, &value)) == 0; record_number++) {
		create_array_prefix(&prefix, "", record_number);
		process_value((const char *) avro_raw_string_get(&prefix), &value);
		avro_value_reset(&value);
	}

	if (rval != EOF) {
		fprintf(stderr, "Error reading value: %s", avro_strerror());
	}

	avro_raw_string_done(&prefix);
	avro_value_decref(&value);
	avro_value_iface_decref(iface);
	avro_file_reader_close(reader);
	avro_schema_decref(wschema);
}


/*-- MAIN PROGRAM --*/
static struct option longopts[] = {
	{ "separator", required_argument, NULL, 's' },
	{ NULL, 0, NULL, 0 }
};

static void usage(void)
{
	fprintf(stderr,
		"Usage: avropipe [--separator=<separator>]\n"
		"                <avro data file>\n");
}


int main(int argc, char **argv)
{
	char  *data_filename;

	int  ch;
	while ((ch = getopt_long(argc, argv, "s:", longopts, NULL) ) != -1) {
		switch (ch) {
			case 's':
				separator = optarg;
				break;

			default:
				usage();
				exit(1);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 1) {
		data_filename = argv[0];
	} else if (argc == 0) {
		data_filename = NULL;
	} else {
		fprintf(stderr, "Can't read from multiple input files.\n");
		usage();
		exit(1);
	}

	/* Process the data file */
	process_file(data_filename);
	return 0;
}
