/*
Copyright 2020 Google LLC

Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/

#include "test-lib.h"
#include "reftable/basics.h"

struct integer_needle_lesseq_args {
	int needle;
	int *haystack;
};

static int integer_needle_lesseq(size_t i, void *_args)
{
	struct integer_needle_lesseq_args *args = _args;
	return args->needle <= args->haystack[i];
}

static void *realloc_stub(void *p UNUSED, size_t size UNUSED)
{
	return NULL;
}

int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
{
	if_test ("binary search with binsearch works") {
		int haystack[] = { 2, 4, 6, 8, 10 };
		struct {
			int needle;
			size_t expected_idx;
		} testcases[] = {
			{-9000, 0},
			{-1, 0},
			{0, 0},
			{2, 0},
			{3, 1},
			{4, 1},
			{7, 3},
			{9, 4},
			{10, 4},
			{11, 5},
			{9000, 5},
		};

		for (size_t i = 0; i < ARRAY_SIZE(testcases); i++) {
			struct integer_needle_lesseq_args args = {
				.haystack = haystack,
				.needle = testcases[i].needle,
			};
			size_t idx;

			idx = binsearch(ARRAY_SIZE(haystack),
					&integer_needle_lesseq, &args);
			check_int(idx, ==, testcases[i].expected_idx);
		}
	}

	if_test ("names_length returns size of a NULL-terminated string array") {
		const char *a[] = { "a", "b", NULL };
		check_int(names_length(a), ==, 2);
	}

	if_test ("names_equal compares NULL-terminated string arrays") {
		const char *a[] = { "a", "b", "c", NULL };
		const char *b[] = { "a", "b", "d", NULL };
		const char *c[] = { "a", "b", NULL };

		check(names_equal(a, a));
		check(!names_equal(a, b));
		check(!names_equal(a, c));
	}

	if_test ("parse_names works for basic input") {
		char in1[] = "line\n";
		char in2[] = "a\nb\nc";
		char **out = parse_names(in1, strlen(in1));
		check(out != NULL);
		check_str(out[0], "line");
		check(!out[1]);
		free_names(out);

		out = parse_names(in2, strlen(in2));
		check(out != NULL);
		check_str(out[0], "a");
		check_str(out[1], "b");
		check_str(out[2], "c");
		check(!out[3]);
		free_names(out);
	}

	if_test ("parse_names drops empty string") {
		char in[] = "a\n\nb\n";
		char **out = parse_names(in, strlen(in));
		check(out != NULL);
		check_str(out[0], "a");
		/* simply '\n' should be dropped as empty string */
		check_str(out[1], "b");
		check(!out[2]);
		free_names(out);
	}

	if_test ("common_prefix_size works") {
		struct reftable_buf a = REFTABLE_BUF_INIT;
		struct reftable_buf b = REFTABLE_BUF_INIT;
		struct {
			const char *a, *b;
			int want;
		} cases[] = {
			{"abcdef", "abc", 3},
			{ "abc", "ab", 2 },
			{ "", "abc", 0 },
			{ "abc", "abd", 2 },
			{ "abc", "pqr", 0 },
		};

		for (size_t i = 0; i < ARRAY_SIZE(cases); i++) {
			check(!reftable_buf_addstr(&a, cases[i].a));
			check(!reftable_buf_addstr(&b, cases[i].b));
			check_int(common_prefix_size(&a, &b), ==, cases[i].want);
			reftable_buf_reset(&a);
			reftable_buf_reset(&b);
		}
		reftable_buf_release(&a);
		reftable_buf_release(&b);
	}

	if_test ("put_be24 and get_be24 work") {
		uint32_t in = 0x112233;
		uint8_t dest[3];
		uint32_t out;
		put_be24(dest, in);
		out = get_be24(dest);
		check_int(in, ==, out);
	}

	if_test ("put_be16 and get_be16 work") {
		uint32_t in = 0xfef1;
		uint8_t dest[3];
		uint32_t out;
		put_be16(dest, in);
		out = get_be16(dest);
		check_int(in, ==, out);
	}

	if_test ("REFTABLE_ALLOC_GROW works") {
		int *arr = NULL, *old_arr;
		size_t alloc = 0, old_alloc;

		check(!REFTABLE_ALLOC_GROW(arr, 1, alloc));
		check(arr != NULL);
		check_uint(alloc, >=, 1);
		arr[0] = 42;

		old_alloc = alloc;
		old_arr = arr;
		reftable_set_alloc(NULL, realloc_stub, NULL);
		check(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc));
		check(arr == old_arr);
		check_uint(alloc, ==, old_alloc);

		old_alloc = alloc;
		reftable_set_alloc(NULL, NULL, NULL);
		check(!REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc));
		check(arr != NULL);
		check_uint(alloc, >, old_alloc);
		arr[alloc - 1] = 42;

		reftable_free(arr);
	}

	if_test ("REFTABLE_ALLOC_GROW_OR_NULL works") {
		int *arr = NULL;
		size_t alloc = 0, old_alloc;

		REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc);
		check(arr != NULL);
		check_uint(alloc, >=, 1);
		arr[0] = 42;

		old_alloc = alloc;
		REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
		check(arr != NULL);
		check_uint(alloc, >, old_alloc);
		arr[alloc - 1] = 42;

		old_alloc = alloc;
		reftable_set_alloc(NULL, realloc_stub, NULL);
		REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
		check(arr == NULL);
		check_uint(alloc, ==, 0);
		reftable_set_alloc(NULL, NULL, NULL);

		reftable_free(arr);
	}

	return test_done();
}
