// SPDX-License-Identifier: GPL-2.0-only
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "debug.h"
#include "tests.h"
#include <api/io.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>

#define TEMPL "/tmp/perf-test-XXXXXX"

#define EXPECT_EQUAL(val, expected)                             \
do {								\
	if (val != expected) {					\
		pr_debug("%s:%d: %d != %d\n",			\
			__FILE__, __LINE__, val, expected);	\
		ret = -1;					\
	}							\
} while (0)

#define EXPECT_EQUAL64(val, expected)                           \
do {								\
	if (val != expected) {					\
		pr_debug("%s:%d: %lld != %lld\n",		\
			__FILE__, __LINE__, val, expected);	\
		ret = -1;					\
	}							\
} while (0)

static int make_test_file(char path[PATH_MAX], const char *contents)
{
	ssize_t contents_len = strlen(contents);
	int fd;

	strcpy(path, TEMPL);
	fd = mkstemp(path);
	if (fd < 0) {
		pr_debug("mkstemp failed");
		return -1;
	}
	if (write(fd, contents, contents_len) < contents_len) {
		pr_debug("short write");
		close(fd);
		unlink(path);
		return -1;
	}
	close(fd);
	return 0;
}

static int setup_test(char path[PATH_MAX], const char *contents,
		      size_t buf_size, struct io *io)
{
	if (make_test_file(path, contents))
		return -1;

	io->fd = open(path, O_RDONLY);
	if (io->fd < 0) {
		pr_debug("Failed to open '%s'\n", path);
		unlink(path);
		return -1;
	}
	io->buf = malloc(buf_size);
	if (io->buf == NULL) {
		pr_debug("Failed to allocate memory");
		close(io->fd);
		unlink(path);
		return -1;
	}
	io__init(io, io->fd, io->buf, buf_size);
	return 0;
}

static void cleanup_test(char path[PATH_MAX], struct io *io)
{
	zfree(&io->buf);
	close(io->fd);
	unlink(path);
}

static int do_test_get_char(const char *test_string, size_t buf_size)
{
	char path[PATH_MAX];
	struct io io;
	int ch, ret = 0;
	size_t i;

	if (setup_test(path, test_string, buf_size, &io))
		return -1;

	for (i = 0; i < strlen(test_string); i++) {
		ch = io__get_char(&io);

		EXPECT_EQUAL(ch, test_string[i]);
		EXPECT_EQUAL(io.eof, false);
	}
	ch = io__get_char(&io);
	EXPECT_EQUAL(ch, -1);
	EXPECT_EQUAL(io.eof, true);

	cleanup_test(path, &io);
	return ret;
}

static int test_get_char(void)
{
	int i, ret = 0;
	size_t j;

	static const char *const test_strings[] = {
		"12345678abcdef90",
		"a\nb\nc\nd\n",
		"\a\b\t\v\f\r",
	};
	for (i = 0; i <= 10; i++) {
		for (j = 0; j < ARRAY_SIZE(test_strings); j++) {
			if (do_test_get_char(test_strings[j], 1 << i))
				ret = -1;
		}
	}
	return ret;
}

static int do_test_get_hex(const char *test_string,
			__u64 val1, int ch1,
			__u64 val2, int ch2,
			__u64 val3, int ch3,
			bool end_eof)
{
	char path[PATH_MAX];
	struct io io;
	int ch, ret = 0;
	__u64 hex;

	if (setup_test(path, test_string, 4, &io))
		return -1;

	ch = io__get_hex(&io, &hex);
	EXPECT_EQUAL64(hex, val1);
	EXPECT_EQUAL(ch, ch1);

	ch = io__get_hex(&io, &hex);
	EXPECT_EQUAL64(hex, val2);
	EXPECT_EQUAL(ch, ch2);

	ch = io__get_hex(&io, &hex);
	EXPECT_EQUAL64(hex, val3);
	EXPECT_EQUAL(ch, ch3);

	EXPECT_EQUAL(io.eof, end_eof);

	cleanup_test(path, &io);
	return ret;
}

static int test_get_hex(void)
{
	int ret = 0;

	if (do_test_get_hex("12345678abcdef90",
				0x12345678abcdef90, -1,
				0, -1,
				0, -1,
				true))
		ret = -1;

	if (do_test_get_hex("1\n2\n3\n",
				1, '\n',
				2, '\n',
				3, '\n',
				false))
		ret = -1;

	if (do_test_get_hex("12345678ABCDEF90;a;b",
				0x12345678abcdef90, ';',
				0xa, ';',
				0xb, -1,
				true))
		ret = -1;

	if (do_test_get_hex("0x1x2x",
				0, 'x',
				1, 'x',
				2, 'x',
				false))
		ret = -1;

	if (do_test_get_hex("x1x",
				0, -2,
				1, 'x',
				0, -1,
				true))
		ret = -1;

	if (do_test_get_hex("10000000000000000000000000000abcdefgh99i",
				0xabcdef, 'g',
				0, -2,
				0x99, 'i',
				false))
		ret = -1;

	return ret;
}

static int do_test_get_dec(const char *test_string,
			__u64 val1, int ch1,
			__u64 val2, int ch2,
			__u64 val3, int ch3,
			bool end_eof)
{
	char path[PATH_MAX];
	struct io io;
	int ch, ret = 0;
	__u64 dec;

	if (setup_test(path, test_string, 4, &io))
		return -1;

	ch = io__get_dec(&io, &dec);
	EXPECT_EQUAL64(dec, val1);
	EXPECT_EQUAL(ch, ch1);

	ch = io__get_dec(&io, &dec);
	EXPECT_EQUAL64(dec, val2);
	EXPECT_EQUAL(ch, ch2);

	ch = io__get_dec(&io, &dec);
	EXPECT_EQUAL64(dec, val3);
	EXPECT_EQUAL(ch, ch3);

	EXPECT_EQUAL(io.eof, end_eof);

	cleanup_test(path, &io);
	return ret;
}

static int test_get_dec(void)
{
	int ret = 0;

	if (do_test_get_dec("12345678abcdef90",
				12345678, 'a',
				0, -2,
				0, -2,
				false))
		ret = -1;

	if (do_test_get_dec("1\n2\n3\n",
				1, '\n',
				2, '\n',
				3, '\n',
				false))
		ret = -1;

	if (do_test_get_dec("12345678;1;2",
				12345678, ';',
				1, ';',
				2, -1,
				true))
		ret = -1;

	if (do_test_get_dec("0x1x2x",
				0, 'x',
				1, 'x',
				2, 'x',
				false))
		ret = -1;

	if (do_test_get_dec("x1x",
				0, -2,
				1, 'x',
				0, -1,
				true))
		ret = -1;

	if (do_test_get_dec("10000000000000000000000000000000000000000000000000000000000123456789ab99c",
				123456789, 'a',
				0, -2,
				99, 'c',
				false))
		ret = -1;

	return ret;
}

static int test_get_line(void)
{
	char path[PATH_MAX];
	struct io io;
	char test_string[1024];
	char *line = NULL;
	size_t i, line_len = 0;
	size_t buf_size = 128;
	int ret = 0;

	for (i = 0; i < 512; i++)
		test_string[i] = 'a';
	test_string[512] = '\n';
	for (i = 513; i < 1023; i++)
		test_string[i] = 'b';
	test_string[1023] = '\0';

	if (setup_test(path, test_string, buf_size, &io))
		return -1;

	EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 513);
	EXPECT_EQUAL((int)strlen(line), 513);
	for (i = 0; i < 512; i++)
		EXPECT_EQUAL(line[i], 'a');
	EXPECT_EQUAL(line[512], '\n');
	EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 510);
	for (i = 0; i < 510; i++)
		EXPECT_EQUAL(line[i], 'b');

	free(line);
	cleanup_test(path, &io);
	return ret;
}

static int test__api_io(struct test_suite *test __maybe_unused,
			int subtest __maybe_unused)
{
	int ret = 0;

	if (test_get_char())
		ret = TEST_FAIL;
	if (test_get_hex())
		ret = TEST_FAIL;
	if (test_get_dec())
		ret = TEST_FAIL;
	if (test_get_line())
		ret = TEST_FAIL;
	return ret;
}

DEFINE_SUITE("Test api io", api_io);
