// SPDX-License-Identifier: GPL-2.0-only
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <asm/papr-vpd.h>

#include "utils.h"

#define DEVPATH "/dev/papr-vpd"

static int dev_papr_vpd_open_close(void)
{
	const int devfd = open(DEVPATH, O_RDONLY);

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");

	FAIL_IF(devfd < 0);
	FAIL_IF(close(devfd) != 0);

	return 0;
}

static int dev_papr_vpd_get_handle_all(void)
{
	const int devfd = open(DEVPATH, O_RDONLY);
	struct papr_location_code lc = { .str = "", };
	off_t size;
	int fd;

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");

	FAIL_IF(devfd < 0);

	errno = 0;
	fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
	FAIL_IF(errno != 0);
	FAIL_IF(fd < 0);

	FAIL_IF(close(devfd) != 0);

	size = lseek(fd, 0, SEEK_END);
	FAIL_IF(size <= 0);

	void *buf = malloc((size_t)size);
	FAIL_IF(!buf);

	ssize_t consumed = pread(fd, buf, size, 0);
	FAIL_IF(consumed != size);

	/* Ensure EOF */
	FAIL_IF(read(fd, buf, size) != 0);
	FAIL_IF(close(fd));

	/* Verify that the buffer looks like VPD */
	static const char needle[] = "System VPD";
	FAIL_IF(!memmem(buf, size, needle, strlen(needle)));

	return 0;
}

static int dev_papr_vpd_get_handle_byte_at_a_time(void)
{
	const int devfd = open(DEVPATH, O_RDONLY);
	struct papr_location_code lc = { .str = "", };
	int fd;

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");

	FAIL_IF(devfd < 0);

	errno = 0;
	fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
	FAIL_IF(errno != 0);
	FAIL_IF(fd < 0);

	FAIL_IF(close(devfd) != 0);

	size_t consumed = 0;
	while (1) {
		ssize_t res;
		char c;

		errno = 0;
		res = read(fd, &c, sizeof(c));
		FAIL_IF(res > sizeof(c));
		FAIL_IF(res < 0);
		FAIL_IF(errno != 0);
		consumed += res;
		if (res == 0)
			break;
	}

	FAIL_IF(consumed != lseek(fd, 0, SEEK_END));

	FAIL_IF(close(fd));

	return 0;
}


static int dev_papr_vpd_unterm_loc_code(void)
{
	const int devfd = open(DEVPATH, O_RDONLY);
	struct papr_location_code lc = {};
	int fd;

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");

	FAIL_IF(devfd < 0);

	/*
	 * Place a non-null byte in every element of loc_code; the
	 * driver should reject this input.
	 */
	memset(lc.str, 'x', ARRAY_SIZE(lc.str));

	errno = 0;
	fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
	FAIL_IF(fd != -1);
	FAIL_IF(errno != EINVAL);

	FAIL_IF(close(devfd) != 0);
	return 0;
}

static int dev_papr_vpd_null_handle(void)
{
	const int devfd = open(DEVPATH, O_RDONLY);
	int rc;

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");

	FAIL_IF(devfd < 0);

	errno = 0;
	rc = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, NULL);
	FAIL_IF(rc != -1);
	FAIL_IF(errno != EFAULT);

	FAIL_IF(close(devfd) != 0);
	return 0;
}

static int papr_vpd_close_handle_without_reading(void)
{
	const int devfd = open(DEVPATH, O_RDONLY);
	struct papr_location_code lc;
	int fd;

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");

	FAIL_IF(devfd < 0);

	errno = 0;
	fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
	FAIL_IF(errno != 0);
	FAIL_IF(fd < 0);

	/* close the handle without reading it */
	FAIL_IF(close(fd) != 0);

	FAIL_IF(close(devfd) != 0);
	return 0;
}

static int papr_vpd_reread(void)
{
	const int devfd = open(DEVPATH, O_RDONLY);
	struct papr_location_code lc = { .str = "", };
	int fd;

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");

	FAIL_IF(devfd < 0);

	errno = 0;
	fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
	FAIL_IF(errno != 0);
	FAIL_IF(fd < 0);

	FAIL_IF(close(devfd) != 0);

	const off_t size = lseek(fd, 0, SEEK_END);
	FAIL_IF(size <= 0);

	char *bufs[2];

	for (size_t i = 0; i < ARRAY_SIZE(bufs); ++i) {
		bufs[i] = malloc(size);
		FAIL_IF(!bufs[i]);
		ssize_t consumed = pread(fd, bufs[i], size, 0);
		FAIL_IF(consumed != size);
	}

	FAIL_IF(memcmp(bufs[0], bufs[1], size));

	FAIL_IF(close(fd) != 0);

	return 0;
}

static int get_system_loc_code(struct papr_location_code *lc)
{
	static const char system_id_path[] = "/sys/firmware/devicetree/base/system-id";
	static const char model_path[] = "/sys/firmware/devicetree/base/model";
	char *system_id;
	char *model;
	int err = -1;

	if (read_file_alloc(model_path, &model, NULL))
		return err;

	if (read_file_alloc(system_id_path, &system_id, NULL))
		goto free_model;

	char *mtm;
	int sscanf_ret = sscanf(model, "IBM,%ms", &mtm);
	if (sscanf_ret != 1)
		goto free_system_id;

	char *plant_and_seq;
	if (sscanf(system_id, "IBM,%*c%*c%ms", &plant_and_seq) != 1)
		goto free_mtm;
	/*
	 * Replace - with . to build location code.
	 */
	char *sep = strchr(mtm, '-');
	if (!sep)
		goto free_mtm;
	else
		*sep = '.';

	snprintf(lc->str, sizeof(lc->str),
		 "U%s.%s", mtm, plant_and_seq);
	err = 0;

	free(plant_and_seq);
free_mtm:
	free(mtm);
free_system_id:
	free(system_id);
free_model:
	free(model);
	return err;
}

static int papr_vpd_system_loc_code(void)
{
	struct papr_location_code lc;
	const int devfd = open(DEVPATH, O_RDONLY);
	off_t size;
	int fd;

	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
		    DEVPATH " not present");
	SKIP_IF_MSG(get_system_loc_code(&lc),
		    "Cannot determine system location code");

	FAIL_IF(devfd < 0);

	errno = 0;
	fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
	FAIL_IF(errno != 0);
	FAIL_IF(fd < 0);

	FAIL_IF(close(devfd) != 0);

	size = lseek(fd, 0, SEEK_END);
	FAIL_IF(size <= 0);

	void *buf = malloc((size_t)size);
	FAIL_IF(!buf);

	ssize_t consumed = pread(fd, buf, size, 0);
	FAIL_IF(consumed != size);

	/* Ensure EOF */
	FAIL_IF(read(fd, buf, size) != 0);
	FAIL_IF(close(fd));

	/* Verify that the buffer looks like VPD */
	static const char needle[] = "System VPD";
	FAIL_IF(!memmem(buf, size, needle, strlen(needle)));

	return 0;
}

struct vpd_test {
	int (*function)(void);
	const char *description;
};

static const struct vpd_test vpd_tests[] = {
	{
		.function = dev_papr_vpd_open_close,
		.description = "open/close " DEVPATH,
	},
	{
		.function = dev_papr_vpd_unterm_loc_code,
		.description = "ensure EINVAL on unterminated location code",
	},
	{
		.function = dev_papr_vpd_null_handle,
		.description = "ensure EFAULT on bad handle addr",
	},
	{
		.function = dev_papr_vpd_get_handle_all,
		.description = "get handle for all VPD"
	},
	{
		.function = papr_vpd_close_handle_without_reading,
		.description = "close handle without consuming VPD"
	},
	{
		.function = dev_papr_vpd_get_handle_byte_at_a_time,
		.description = "read all VPD one byte at a time"
	},
	{
		.function = papr_vpd_reread,
		.description = "ensure re-read yields same results"
	},
	{
		.function = papr_vpd_system_loc_code,
		.description = "get handle for system VPD"
	},
};

int main(void)
{
	size_t fails = 0;

	for (size_t i = 0; i < ARRAY_SIZE(vpd_tests); ++i) {
		const struct vpd_test *t = &vpd_tests[i];

		if (test_harness(t->function, t->description))
			++fails;
	}

	return fails == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
