/*
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 "unit-test.h"
#include "lib-reftable.h"
#include "reftable/basics.h"
#include "reftable/reftable-error.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;
}

void test_reftable_basics__binsearch(void)
{
	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);
		cl_assert_equal_i(idx, testcases[i].expected_idx);
	}
}

void test_reftable_basics__names_length(void)
{
	const char *a[] = { "a", "b", NULL };
	cl_assert_equal_i(names_length(a), 2);
}

void test_reftable_basics__names_equal(void)
{
	const char *a[] = { "a", "b", "c", NULL };
	const char *b[] = { "a", "b", "d", NULL };
	const char *c[] = { "a", "b", NULL };

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

void test_reftable_basics__parse_names(void)
{
	char in1[] = "line\n";
	char in2[] = "a\nb\nc\n";
	char **out = NULL;
	int err = parse_names(in1, strlen(in1), &out);
	cl_assert(err == 0);
	cl_assert(out != NULL);
	cl_assert_equal_s(out[0], "line");
	cl_assert(!out[1]);
	free_names(out);

	out = NULL;
	err = parse_names(in2, strlen(in2), &out);
	cl_assert(err == 0);
	cl_assert(out != NULL);
	cl_assert_equal_s(out[0], "a");
	cl_assert_equal_s(out[1], "b");
	cl_assert_equal_s(out[2], "c");
	cl_assert(!out[3]);
	free_names(out);
}

void test_reftable_basics__parse_names_missing_newline(void)
{
	char in1[] = "line\nline2";
	char **out = NULL;
	int err = parse_names(in1, strlen(in1), &out);
	cl_assert(err == REFTABLE_FORMAT_ERROR);
	cl_assert(out == NULL);
}

void test_reftable_basics__parse_names_drop_empty_string(void)
{
	char in[] = "a\n\nb\n";
	char **out = NULL;
	int err = parse_names(in, strlen(in), &out);
	cl_assert(err == 0);
	cl_assert(out != NULL);
	cl_assert_equal_s(out[0], "a");
	/* simply '\n' should be dropped as empty string */
	cl_assert_equal_s(out[1], "b");
	cl_assert(out[2] == NULL);
	free_names(out);
}

void test_reftable_basics__common_prefix_size(void)
{
	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++) {
		cl_assert_equal_i(reftable_buf_addstr(&a, cases[i].a), 0);
		cl_assert_equal_i(reftable_buf_addstr(&b, cases[i].b), 0);
		cl_assert_equal_i(common_prefix_size(&a, &b), cases[i].want);
		reftable_buf_reset(&a);
		reftable_buf_reset(&b);
	}
	reftable_buf_release(&a);
	reftable_buf_release(&b);
}

void test_reftable_basics__put_get_be64(void)
{
	uint64_t in = 0x1122334455667788;
	uint8_t dest[8];
	uint64_t out;
	reftable_put_be64(dest, in);
	out = reftable_get_be64(dest);
	cl_assert(in == out);
}

void test_reftable_basics__put_get_be32(void)
{
	uint32_t in = 0x11223344;
	uint8_t dest[4];
	uint32_t out;
	reftable_put_be32(dest, in);
	out = reftable_get_be32(dest);
	cl_assert_equal_i(in, out);
}

void test_reftable_basics__put_get_be24(void)
{
	uint32_t in = 0x112233;
	uint8_t dest[3];
	uint32_t out;
	reftable_put_be24(dest, in);
	out = reftable_get_be24(dest);
	cl_assert_equal_i(in, out);
}

void test_reftable_basics__put_get_be16(void)
{
	uint32_t in = 0xfef1;
	uint8_t dest[3];
	uint32_t out;
	reftable_put_be16(dest, in);
	out = reftable_get_be16(dest);
	cl_assert_equal_i(in, out);
}

void test_reftable_basics__alloc_grow(void)
{
	int *arr = NULL, *old_arr;
	size_t alloc = 0, old_alloc;

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

	old_alloc = alloc;
	old_arr = arr;
	reftable_set_alloc(NULL, realloc_stub, NULL);
	cl_assert(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc));
	cl_assert(arr == old_arr);
	cl_assert_equal_i(alloc, old_alloc);

	old_alloc = alloc;
	reftable_set_alloc(NULL, NULL, NULL);
	cl_assert_equal_i(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc), 0);
	cl_assert(arr != NULL);
	cl_assert(alloc > old_alloc);
	arr[alloc - 1] = 42;

	reftable_free(arr);
}

void test_reftable_basics__alloc_grow_or_null(void)
{
	int *arr = NULL;
	size_t alloc = 0, old_alloc;

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

	old_alloc = alloc;
	REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
	cl_assert(arr != NULL);
	cl_assert(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);
	cl_assert(arr == NULL);
	cl_assert_equal_i(alloc, 0);
	reftable_set_alloc(NULL, NULL, NULL);

	reftable_free(arr);
}
