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

#include <libvfio.h>

#define readlink_safe(_path, _buf) ({					\
	int __ret;							\
									\
	_Static_assert(!__builtin_types_compatible_p(			\
		__typeof__(_buf), char *),				\
	    "readlink_safe: _buf must be an array, not a pointer");	\
									\
	__ret = readlink(_path, _buf, sizeof(_buf) - 1);		\
	if (__ret != -1)						\
		_buf[__ret] = 0;					\
	__ret;								\
})

static void readlink_base(const char *path, const char *data_fmt, void *out_data)
{
	char rl_path[PATH_MAX];
	int ret;

	ret = readlink_safe(path, rl_path);
	VFIO_ASSERT_NE(ret, -1);

	ret = sscanf(basename(rl_path), data_fmt, out_data);
	VFIO_ASSERT_EQ(ret, 1);
}

static int sysfs_val_get_int(const char *component, const char *name,
			     const char *file)
{
	char path[PATH_MAX];
	char buf[32];
	int ret;
	int fd;

	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/%s/%s/%s", component, name, file);
	fd = open(path, O_RDONLY);
	if (fd < 0)
		return fd;

	VFIO_ASSERT_GT(read(fd, buf, ARRAY_SIZE(buf)), 0);
	VFIO_ASSERT_EQ(close(fd), 0);

	errno = 0;
	ret = strtol(buf, NULL, 0);
	VFIO_ASSERT_EQ(errno, 0, "sysfs path \"%s\" is not an integer: \"%s\"\n", path, buf);

	return ret;
}

static void sysfs_val_set(const char *component, const char *name,
			  const char *file, const char *val)
{
	char path[PATH_MAX];
	int fd;

	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/%s/%s/%s", component, name, file);
	VFIO_ASSERT_GT(fd = open(path, O_WRONLY), 0);

	VFIO_ASSERT_EQ(write(fd, val, strlen(val)), strlen(val));
	VFIO_ASSERT_EQ(close(fd), 0);
}

static int sysfs_device_val_get(const char *bdf, const char *file)
{
	return sysfs_val_get_int("devices", bdf, file);
}

static void sysfs_device_val_set(const char *bdf, const char *file, const char *val)
{
	sysfs_val_set("devices", bdf, file, val);
}

static void sysfs_device_val_set_int(const char *bdf, const char *file, int val)
{
	char val_str[32];

	snprintf_assert(val_str, sizeof(val_str), "%d", val);
	sysfs_device_val_set(bdf, file, val_str);
}

int sysfs_sriov_totalvfs_get(const char *bdf)
{
	return sysfs_device_val_get(bdf, "sriov_totalvfs");
}

int sysfs_sriov_numvfs_get(const char *bdf)
{
	return sysfs_device_val_get(bdf, "sriov_numvfs");
}

void sysfs_sriov_numvfs_set(const char *bdf, int numvfs)
{
	sysfs_device_val_set_int(bdf, "sriov_numvfs", numvfs);
}

char *sysfs_sriov_vf_bdf_get(const char *pf_bdf, int i)
{
	char path[PATH_MAX];
	char *out_vf_bdf;

	/* Fit "0000:00:00.0" */
	out_vf_bdf = calloc_assert(16, sizeof(char));

	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/devices/%s/virtfn%d", pf_bdf, i);
	readlink_base(path, "%s", out_vf_bdf);

	return out_vf_bdf;
}

int sysfs_iommu_group_get(const char *bdf)
{
	char path[PATH_MAX];
	int group;

	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/devices/%s/iommu_group", bdf);
	readlink_base(path, "%d", &group);

	return group;
}

char *sysfs_driver_get(const char *bdf)
{
	char driver_path[PATH_MAX];
	char path[PATH_MAX];
	char *out_driver;
	int ret;

	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/devices/%s/driver", bdf);
	ret = readlink_safe(path, driver_path);
	if (ret == -1) {
		if (errno == ENOENT)
			return NULL;

		VFIO_FAIL("Failed to read %s\n", path);
	}

	out_driver = strdup(basename(driver_path));
	VFIO_ASSERT_NOT_NULL(out_driver);

	return out_driver;
}
