/*
 * CDDL HEADER START
 *
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 *
 * CDDL HEADER END
 */

/*
 * Copyright (c) 2016 by Delphix. All rights reserved.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <libzfs_core.h>
#include <sys/nvpair.h>

nvlist_t *nvl;
const char *pool;
boolean_t unexpected_failures;

static boolean_t
nvlist_equal(nvlist_t *nvla, nvlist_t *nvlb)
{
	if (fnvlist_num_pairs(nvla) != fnvlist_num_pairs(nvlb))
		return (B_FALSE);
	/*
	 * The nvlists have the same number of pairs and keys are unique, so
	 * if every key in A is also in B and assigned to the same value, the
	 * lists are identical.
	 */
	for (nvpair_t *pair = nvlist_next_nvpair(nvla, NULL);
	    pair != NULL; pair = nvlist_next_nvpair(nvla, pair)) {
		char *key = nvpair_name(pair);

		if (!nvlist_exists(nvlb, key))
			return (B_FALSE);

		if (nvpair_type(pair) !=
		    nvpair_type(fnvlist_lookup_nvpair(nvlb, key)))
			return (B_FALSE);

		switch (nvpair_type(pair)) {
		case DATA_TYPE_BOOLEAN_VALUE:
			if (fnvpair_value_boolean_value(pair) !=
			    fnvlist_lookup_boolean_value(nvlb, key)) {
				return (B_FALSE);
			}
			break;
		case DATA_TYPE_STRING:
			if (strcmp(fnvpair_value_string(pair),
			    fnvlist_lookup_string(nvlb, key))) {
				return (B_FALSE);
			}
			break;
		case DATA_TYPE_INT64:
			if (fnvpair_value_int64(pair) !=
			    fnvlist_lookup_int64(nvlb, key)) {
				return (B_FALSE);
			}
			break;
		case DATA_TYPE_NVLIST:
			if (!nvlist_equal(fnvpair_value_nvlist(pair),
			    fnvlist_lookup_nvlist(nvlb, key))) {
				return (B_FALSE);
			}
			break;
		default:
			(void) printf("Unexpected type for nvlist_equal\n");
			return (B_FALSE);
		}
	}
	return (B_TRUE);
}

static void
test(const char *testname, boolean_t expect_success, boolean_t expect_match)
{
	char *progstr = "input = ...; return {output=input}";

	nvlist_t *outnvl;

	(void) printf("\nrunning test '%s'; input:\n", testname);
	dump_nvlist(nvl, 4);

	int err = lzc_channel_program(pool, progstr,
	    10 * 1000 * 1000, 10 * 1024 * 1024, nvl, &outnvl);

	(void) printf("lzc_channel_program returned %u\n", err);
	dump_nvlist(outnvl, 5);

	if (err == 0 && expect_match) {
		/*
		 * Verify that outnvl is the same as input nvl, if we expect
		 * them to be. The input and output will never match if the
		 * input contains an array (since arrays are converted to lua
		 * tables), so this is only asserted for some test cases.
		 */
		nvlist_t *real_outnvl = fnvlist_lookup_nvlist(outnvl, "return");
		real_outnvl = fnvlist_lookup_nvlist(real_outnvl, "output");
		if (!nvlist_equal(nvl, real_outnvl)) {
			unexpected_failures = B_TRUE;
			(void) printf("unexpected input/output mismatch for "
			    "case: %s\n", testname);
		}
	}
	if (err != 0 && expect_success) {
		unexpected_failures = B_TRUE;
		(void) printf("unexpected FAIL of case: %s\n", testname);
	}

	fnvlist_free(nvl);
	nvl = fnvlist_alloc();
}

static void
run_tests(void)
{
	const char *key = "key";

	/* Note: maximum nvlist key length is 32KB */
	int len = 1024 * 31;
	char *bigstring = malloc(len);
	for (int i = 0; i < len; i++)
		bigstring[i] = 'a' + i % 26;
	bigstring[len - 1] = '\0';

	nvl = fnvlist_alloc();

	fnvlist_add_boolean(nvl, key);
	test("boolean", B_TRUE, B_FALSE);

	fnvlist_add_boolean_value(nvl, key, B_TRUE);
	test("boolean_value", B_FALSE, B_FALSE);

	fnvlist_add_byte(nvl, key, 1);
	test("byte", B_FALSE, B_FALSE);

	fnvlist_add_int8(nvl, key, 1);
	test("int8", B_FALSE, B_FALSE);

	fnvlist_add_uint8(nvl, key, 1);
	test("uint8", B_FALSE, B_FALSE);

	fnvlist_add_int16(nvl, key, 1);
	test("int16", B_FALSE, B_FALSE);

	fnvlist_add_uint16(nvl, key, 1);
	test("uint16", B_FALSE, B_FALSE);

	fnvlist_add_int32(nvl, key, 1);
	test("int32", B_FALSE, B_FALSE);

	fnvlist_add_uint32(nvl, key, 1);
	test("uint32", B_FALSE, B_FALSE);

	fnvlist_add_int64(nvl, key, 1);
	test("int64", B_TRUE, B_TRUE);

	fnvlist_add_uint64(nvl, key, 1);
	test("uint64", B_FALSE, B_FALSE);

	fnvlist_add_string(nvl, key, "1");
	test("string", B_TRUE, B_TRUE);


	{
		nvlist_t *val = fnvlist_alloc();
		fnvlist_add_string(val, "subkey", "subvalue");
		fnvlist_add_nvlist(nvl, key, val);
		fnvlist_free(val);
		test("nvlist", B_TRUE, B_TRUE);
	}
	{
		boolean_t val[2] = { B_FALSE, B_TRUE };
		fnvlist_add_boolean_array(nvl, key, val, 2);
		test("boolean_array", B_FALSE, B_FALSE);
	}
	{
		uchar_t val[2] = { 0, 1 };
		fnvlist_add_byte_array(nvl, key, val, 2);
		test("byte_array", B_FALSE, B_FALSE);
	}
	{
		int8_t val[2] = { 0, 1 };
		fnvlist_add_int8_array(nvl, key, val, 2);
		test("int8_array", B_FALSE, B_FALSE);
	}
	{
		uint8_t val[2] = { 0, 1 };
		fnvlist_add_uint8_array(nvl, key, val, 2);
		test("uint8_array", B_FALSE, B_FALSE);
	}
	{
		int16_t val[2] = { 0, 1 };
		fnvlist_add_int16_array(nvl, key, val, 2);
		test("int16_array", B_FALSE, B_FALSE);
	}
	{
		uint16_t val[2] = { 0, 1 };
		fnvlist_add_uint16_array(nvl, key, val, 2);
		test("uint16_array", B_FALSE, B_FALSE);
	}
	{
		int32_t val[2] = { 0, 1 };
		fnvlist_add_int32_array(nvl, key, val, 2);
		test("int32_array", B_FALSE, B_FALSE);
	}
	{
		uint32_t val[2] = { 0, 1 };
		fnvlist_add_uint32_array(nvl, key, val, 2);
		test("uint32_array", B_FALSE, B_FALSE);
	}
	{
		int64_t val[2] = { 0, 1 };
		fnvlist_add_int64_array(nvl, key, val, 2);
		test("int64_array", B_TRUE, B_FALSE);
	}
	{
		uint64_t val[2] = { 0, 1 };
		fnvlist_add_uint64_array(nvl, key, val, 2);
		test("uint64_array", B_FALSE, B_FALSE);
	}
	{
		char *const val[2] = { "0", "1" };
		fnvlist_add_string_array(nvl, key, val, 2);
		test("string_array", B_TRUE, B_FALSE);
	}
	{
		nvlist_t *val[2];
		val[0] = fnvlist_alloc();
		fnvlist_add_string(val[0], "subkey", "subvalue");
		val[1] = fnvlist_alloc();
		fnvlist_add_string(val[1], "subkey2", "subvalue2");
		fnvlist_add_nvlist_array(nvl, key, val, 2);
		fnvlist_free(val[0]);
		fnvlist_free(val[1]);
		test("nvlist_array", B_FALSE, B_FALSE);
	}
	{
		fnvlist_add_string(nvl, bigstring, "1");
		test("large_key", B_TRUE, B_TRUE);
	}
	{
		fnvlist_add_string(nvl, key, bigstring);
		test("large_value", B_TRUE, B_TRUE);
	}
	{
		for (int i = 0; i < 1024; i++) {
			char buf[32];
			(void) snprintf(buf, sizeof (buf), "key-%u", i);
			fnvlist_add_int64(nvl, buf, i);
		}
		test("many_keys", B_TRUE, B_TRUE);
	}
#ifndef __sparc__
	{
		for (int i = 0; i < 10; i++) {
			nvlist_t *newval = fnvlist_alloc();
			fnvlist_add_nvlist(newval, "key", nvl);
			fnvlist_free(nvl);
			nvl = newval;
		}
		test("deeply_nested_pos", B_TRUE, B_TRUE);
	}
	{
		for (int i = 0; i < 90; i++) {
			nvlist_t *newval = fnvlist_alloc();
			fnvlist_add_nvlist(newval, "key", nvl);
			fnvlist_free(nvl);
			nvl = newval;
		}
		test("deeply_nested_neg", B_FALSE, B_FALSE);
	}
#endif
	free(bigstring);
	fnvlist_free(nvl);
}

int
main(int argc, const char *argv[])
{
	(void) libzfs_core_init();

	if (argc != 2) {
		(void) printf("usage: %s <pool>\n",
		    argv[0]);
		exit(2);
	}
	pool = argv[1];

	run_tests();

	libzfs_core_fini();
	return (unexpected_failures);
}
