// SPDX-License-Identifier: GPL-2.0
#include <sys/param.h>
#include <sys/utsname.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <api/fs/fs.h>
#include <linux/zalloc.h>
#include <perf/cpumap.h>

#include "cputopo.h"
#include "cpumap.h"
#include "debug.h"
#include "env.h"
#include "pmu-hybrid.h"

#define PACKAGE_CPUS_FMT \
	"%s/devices/system/cpu/cpu%d/topology/package_cpus_list"
#define PACKAGE_CPUS_FMT_OLD \
	"%s/devices/system/cpu/cpu%d/topology/core_siblings_list"
#define DIE_CPUS_FMT \
	"%s/devices/system/cpu/cpu%d/topology/die_cpus_list"
#define CORE_CPUS_FMT \
	"%s/devices/system/cpu/cpu%d/topology/core_cpus_list"
#define CORE_CPUS_FMT_OLD \
	"%s/devices/system/cpu/cpu%d/topology/thread_siblings_list"
#define NODE_ONLINE_FMT \
	"%s/devices/system/node/online"
#define NODE_MEMINFO_FMT \
	"%s/devices/system/node/node%d/meminfo"
#define NODE_CPULIST_FMT \
	"%s/devices/system/node/node%d/cpulist"

static int build_cpu_topology(struct cpu_topology *tp, int cpu)
{
	FILE *fp;
	char filename[MAXPATHLEN];
	char *buf = NULL, *p;
	size_t len = 0;
	ssize_t sret;
	u32 i = 0;
	int ret = -1;

	scnprintf(filename, MAXPATHLEN, PACKAGE_CPUS_FMT,
		  sysfs__mountpoint(), cpu);
	if (access(filename, F_OK) == -1) {
		scnprintf(filename, MAXPATHLEN, PACKAGE_CPUS_FMT_OLD,
			sysfs__mountpoint(), cpu);
	}
	fp = fopen(filename, "r");
	if (!fp)
		goto try_dies;

	sret = getline(&buf, &len, fp);
	fclose(fp);
	if (sret <= 0)
		goto try_dies;

	p = strchr(buf, '\n');
	if (p)
		*p = '\0';

	for (i = 0; i < tp->package_cpus_lists; i++) {
		if (!strcmp(buf, tp->package_cpus_list[i]))
			break;
	}
	if (i == tp->package_cpus_lists) {
		tp->package_cpus_list[i] = buf;
		tp->package_cpus_lists++;
		buf = NULL;
		len = 0;
	}
	ret = 0;

try_dies:
	if (!tp->die_cpus_list)
		goto try_threads;

	scnprintf(filename, MAXPATHLEN, DIE_CPUS_FMT,
		  sysfs__mountpoint(), cpu);
	fp = fopen(filename, "r");
	if (!fp)
		goto try_threads;

	sret = getline(&buf, &len, fp);
	fclose(fp);
	if (sret <= 0)
		goto try_threads;

	p = strchr(buf, '\n');
	if (p)
		*p = '\0';

	for (i = 0; i < tp->die_cpus_lists; i++) {
		if (!strcmp(buf, tp->die_cpus_list[i]))
			break;
	}
	if (i == tp->die_cpus_lists) {
		tp->die_cpus_list[i] = buf;
		tp->die_cpus_lists++;
		buf = NULL;
		len = 0;
	}
	ret = 0;

try_threads:
	scnprintf(filename, MAXPATHLEN, CORE_CPUS_FMT,
		  sysfs__mountpoint(), cpu);
	if (access(filename, F_OK) == -1) {
		scnprintf(filename, MAXPATHLEN, CORE_CPUS_FMT_OLD,
			  sysfs__mountpoint(), cpu);
	}
	fp = fopen(filename, "r");
	if (!fp)
		goto done;

	if (getline(&buf, &len, fp) <= 0)
		goto done;

	p = strchr(buf, '\n');
	if (p)
		*p = '\0';

	for (i = 0; i < tp->core_cpus_lists; i++) {
		if (!strcmp(buf, tp->core_cpus_list[i]))
			break;
	}
	if (i == tp->core_cpus_lists) {
		tp->core_cpus_list[i] = buf;
		tp->core_cpus_lists++;
		buf = NULL;
	}
	ret = 0;
done:
	if (fp)
		fclose(fp);
	free(buf);
	return ret;
}

void cpu_topology__delete(struct cpu_topology *tp)
{
	u32 i;

	if (!tp)
		return;

	for (i = 0 ; i < tp->package_cpus_lists; i++)
		zfree(&tp->package_cpus_list[i]);

	for (i = 0 ; i < tp->die_cpus_lists; i++)
		zfree(&tp->die_cpus_list[i]);

	for (i = 0 ; i < tp->core_cpus_lists; i++)
		zfree(&tp->core_cpus_list[i]);

	free(tp);
}

static bool has_die_topology(void)
{
	char filename[MAXPATHLEN];
	struct utsname uts;

	if (uname(&uts) < 0)
		return false;

	if (strncmp(uts.machine, "x86_64", 6))
		return false;

	scnprintf(filename, MAXPATHLEN, DIE_CPUS_FMT,
		  sysfs__mountpoint(), 0);
	if (access(filename, F_OK) == -1)
		return false;

	return true;
}

struct cpu_topology *cpu_topology__new(void)
{
	struct cpu_topology *tp = NULL;
	void *addr;
	u32 nr, i, nr_addr;
	size_t sz;
	long ncpus;
	int ret = -1;
	struct perf_cpu_map *map;
	bool has_die = has_die_topology();

	ncpus = cpu__max_present_cpu();

	/* build online CPU map */
	map = perf_cpu_map__new(NULL);
	if (map == NULL) {
		pr_debug("failed to get system cpumap\n");
		return NULL;
	}

	nr = (u32)(ncpus & UINT_MAX);

	sz = nr * sizeof(char *);
	if (has_die)
		nr_addr = 3;
	else
		nr_addr = 2;
	addr = calloc(1, sizeof(*tp) + nr_addr * sz);
	if (!addr)
		goto out_free;

	tp = addr;
	addr += sizeof(*tp);
	tp->package_cpus_list = addr;
	addr += sz;
	if (has_die) {
		tp->die_cpus_list = addr;
		addr += sz;
	}
	tp->core_cpus_list = addr;

	for (i = 0; i < nr; i++) {
		if (!cpu_map__has(map, i))
			continue;

		ret = build_cpu_topology(tp, i);
		if (ret < 0)
			break;
	}

out_free:
	perf_cpu_map__put(map);
	if (ret) {
		cpu_topology__delete(tp);
		tp = NULL;
	}
	return tp;
}

static int load_numa_node(struct numa_topology_node *node, int nr)
{
	char str[MAXPATHLEN];
	char field[32];
	char *buf = NULL, *p;
	size_t len = 0;
	int ret = -1;
	FILE *fp;
	u64 mem;

	node->node = (u32) nr;

	scnprintf(str, MAXPATHLEN, NODE_MEMINFO_FMT,
		  sysfs__mountpoint(), nr);
	fp = fopen(str, "r");
	if (!fp)
		return -1;

	while (getline(&buf, &len, fp) > 0) {
		/* skip over invalid lines */
		if (!strchr(buf, ':'))
			continue;
		if (sscanf(buf, "%*s %*d %31s %"PRIu64, field, &mem) != 2)
			goto err;
		if (!strcmp(field, "MemTotal:"))
			node->mem_total = mem;
		if (!strcmp(field, "MemFree:"))
			node->mem_free = mem;
		if (node->mem_total && node->mem_free)
			break;
	}

	fclose(fp);
	fp = NULL;

	scnprintf(str, MAXPATHLEN, NODE_CPULIST_FMT,
		  sysfs__mountpoint(), nr);

	fp = fopen(str, "r");
	if (!fp)
		return -1;

	if (getline(&buf, &len, fp) <= 0)
		goto err;

	p = strchr(buf, '\n');
	if (p)
		*p = '\0';

	node->cpus = buf;
	fclose(fp);
	return 0;

err:
	free(buf);
	if (fp)
		fclose(fp);
	return ret;
}

struct numa_topology *numa_topology__new(void)
{
	struct perf_cpu_map *node_map = NULL;
	struct numa_topology *tp = NULL;
	char path[MAXPATHLEN];
	char *buf = NULL;
	size_t len = 0;
	u32 nr, i;
	FILE *fp;
	char *c;

	scnprintf(path, MAXPATHLEN, NODE_ONLINE_FMT,
		  sysfs__mountpoint());

	fp = fopen(path, "r");
	if (!fp)
		return NULL;

	if (getline(&buf, &len, fp) <= 0)
		goto out;

	c = strchr(buf, '\n');
	if (c)
		*c = '\0';

	node_map = perf_cpu_map__new(buf);
	if (!node_map)
		goto out;

	nr = (u32) node_map->nr;

	tp = zalloc(sizeof(*tp) + sizeof(tp->nodes[0])*nr);
	if (!tp)
		goto out;

	tp->nr = nr;

	for (i = 0; i < nr; i++) {
		if (load_numa_node(&tp->nodes[i], node_map->map[i])) {
			numa_topology__delete(tp);
			tp = NULL;
			break;
		}
	}

out:
	free(buf);
	fclose(fp);
	perf_cpu_map__put(node_map);
	return tp;
}

void numa_topology__delete(struct numa_topology *tp)
{
	u32 i;

	for (i = 0; i < tp->nr; i++)
		zfree(&tp->nodes[i].cpus);

	free(tp);
}

static int load_hybrid_node(struct hybrid_topology_node *node,
			    struct perf_pmu *pmu)
{
	const char *sysfs;
	char path[PATH_MAX];
	char *buf = NULL, *p;
	FILE *fp;
	size_t len = 0;

	node->pmu_name = strdup(pmu->name);
	if (!node->pmu_name)
		return -1;

	sysfs = sysfs__mountpoint();
	if (!sysfs)
		goto err;

	snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, pmu->name);
	fp = fopen(path, "r");
	if (!fp)
		goto err;

	if (getline(&buf, &len, fp) <= 0) {
		fclose(fp);
		goto err;
	}

	p = strchr(buf, '\n');
	if (p)
		*p = '\0';

	fclose(fp);
	node->cpus = buf;
	return 0;

err:
	zfree(&node->pmu_name);
	free(buf);
	return -1;
}

struct hybrid_topology *hybrid_topology__new(void)
{
	struct perf_pmu *pmu;
	struct hybrid_topology *tp = NULL;
	u32 nr, i = 0;

	nr = perf_pmu__hybrid_pmu_num();
	if (nr == 0)
		return NULL;

	tp = zalloc(sizeof(*tp) + sizeof(tp->nodes[0]) * nr);
	if (!tp)
		return NULL;

	tp->nr = nr;
	perf_pmu__for_each_hybrid_pmu(pmu) {
		if (load_hybrid_node(&tp->nodes[i], pmu)) {
			hybrid_topology__delete(tp);
			return NULL;
		}
		i++;
	}

	return tp;
}

void hybrid_topology__delete(struct hybrid_topology *tp)
{
	u32 i;

	for (i = 0; i < tp->nr; i++) {
		zfree(&tp->nodes[i].pmu_name);
		zfree(&tp->nodes[i].cpus);
	}

	free(tp);
}
