// SPDX-License-Identifier: GPL-2.0
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <perf/cpumap.h>
#include "cpumap.h"
#include "tests.h"
#include "session.h"
#include "evlist.h"
#include "debug.h"
#include "pmus.h"
#include <linux/err.h>

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

static int get_temp(char *path)
{
	int fd;

	strcpy(path, TEMPL);

	fd = mkstemp(path);
	if (fd < 0) {
		perror("mkstemp failed");
		return -1;
	}

	close(fd);
	return 0;
}

static int session_write_header(char *path)
{
	struct perf_session *session;
	struct perf_data data = {
		.path = path,
		.mode = PERF_DATA_MODE_WRITE,
	};

	session = perf_session__new(&data, NULL);
	TEST_ASSERT_VAL("can't get session", !IS_ERR(session));

	session->evlist = evlist__new_default();
	TEST_ASSERT_VAL("can't get evlist", session->evlist);

	perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
	perf_header__set_feat(&session->header, HEADER_NRCPUS);
	perf_header__set_feat(&session->header, HEADER_ARCH);

	session->header.data_size += DATA_SIZE;

	TEST_ASSERT_VAL("failed to write header",
			!perf_session__write_header(session, session->evlist, data.file.fd, true));

	evlist__delete(session->evlist);
	perf_session__delete(session);

	return 0;
}

static int check_cpu_topology(char *path, struct perf_cpu_map *map)
{
	struct perf_session *session;
	struct perf_data data = {
		.path = path,
		.mode = PERF_DATA_MODE_READ,
	};
	int i;
	struct aggr_cpu_id id;
	struct perf_cpu cpu;

	session = perf_session__new(&data, NULL);
	TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
	cpu__setup_cpunode_map();

	/* On platforms with large numbers of CPUs process_cpu_topology()
	 * might issue an error while reading the perf.data file section
	 * HEADER_CPU_TOPOLOGY and the cpu_topology_map pointed to by member
	 * cpu is a NULL pointer.
	 * Example: On s390
	 *   CPU 0 is on core_id 0 and physical_package_id 6
	 *   CPU 1 is on core_id 1 and physical_package_id 3
	 *
	 *   Core_id and physical_package_id are platform and architecture
	 *   dependent and might have higher numbers than the CPU id.
	 *   This actually depends on the configuration.
	 *
	 *  In this case process_cpu_topology() prints error message:
	 *  "socket_id number is too big. You may need to upgrade the
	 *  perf tool."
	 *
	 *  This is the reason why this test might be skipped. aarch64 and
	 *  s390 always write this part of the header, even when the above
	 *  condition is true (see do_core_id_test in header.c). So always
	 *  run this test on those platforms.
	 */
	if (!session->header.env.cpu
			&& strncmp(session->header.env.arch, "s390", 4)
			&& strncmp(session->header.env.arch, "aarch64", 7))
		return TEST_SKIP;

	/*
	 * In powerpc pSeries platform, not all the topology information
	 * are exposed via sysfs. Due to restriction, detail like
	 * physical_package_id will be set to -1. Hence skip this
	 * test if physical_package_id returns -1 for cpu from perf_cpu_map.
	 */
	if (!strncmp(session->header.env.arch, "ppc64le", 7)) {
		if (cpu__get_socket_id(perf_cpu_map__cpu(map, 0)) == -1)
			return TEST_SKIP;
	}

	TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);

	for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
		cpu.cpu = i;
		if (!perf_cpu_map__has(map, cpu))
			continue;
		pr_debug("CPU %d, core %d, socket %d\n", i,
			 session->header.env.cpu[i].core_id,
			 session->header.env.cpu[i].socket_id);
	}

	// Test that CPU ID contains socket, die, core and CPU
	perf_cpu_map__for_each_cpu(cpu, i, map) {
		id = aggr_cpu_id__cpu(cpu, NULL);
		TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match",
				cpu.cpu == id.cpu.cpu);

		TEST_ASSERT_VAL("Cpu map - Core ID doesn't match",
			session->header.env.cpu[cpu.cpu].core_id == id.core);
		TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match",
			session->header.env.cpu[cpu.cpu].socket_id ==
			id.socket);

		TEST_ASSERT_VAL("Cpu map - Die ID doesn't match",
			session->header.env.cpu[cpu.cpu].die_id == id.die);
		TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node == -1);
		TEST_ASSERT_VAL("Cpu map - Thread IDX is set", id.thread_idx == -1);
	}

	// Test that core ID contains socket, die and core
	perf_cpu_map__for_each_cpu(cpu, i, map) {
		id = aggr_cpu_id__core(cpu, NULL);
		TEST_ASSERT_VAL("Core map - Core ID doesn't match",
			session->header.env.cpu[cpu.cpu].core_id == id.core);

		TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
			session->header.env.cpu[cpu.cpu].socket_id ==
			id.socket);

		TEST_ASSERT_VAL("Core map - Die ID doesn't match",
			session->header.env.cpu[cpu.cpu].die_id == id.die);
		TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
		TEST_ASSERT_VAL("Core map - Thread IDX is set", id.thread_idx == -1);
	}

	// Test that die ID contains socket and die
	perf_cpu_map__for_each_cpu(cpu, i, map) {
		id = aggr_cpu_id__die(cpu, NULL);
		TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
			session->header.env.cpu[cpu.cpu].socket_id ==
			id.socket);

		TEST_ASSERT_VAL("Die map - Die ID doesn't match",
			session->header.env.cpu[cpu.cpu].die_id == id.die);

		TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1);
		TEST_ASSERT_VAL("Die map - Core is set", id.core == -1);
		TEST_ASSERT_VAL("Die map - CPU is set", id.cpu.cpu == -1);
		TEST_ASSERT_VAL("Die map - Thread IDX is set", id.thread_idx == -1);
	}

	// Test that socket ID contains only socket
	perf_cpu_map__for_each_cpu(cpu, i, map) {
		id = aggr_cpu_id__socket(cpu, NULL);
		TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
			session->header.env.cpu[cpu.cpu].socket_id ==
			id.socket);

		TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
		TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1);
		TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1);
		TEST_ASSERT_VAL("Socket map - CPU is set", id.cpu.cpu == -1);
		TEST_ASSERT_VAL("Socket map - Thread IDX is set", id.thread_idx == -1);
	}

	// Test that node ID contains only node
	perf_cpu_map__for_each_cpu(cpu, i, map) {
		id = aggr_cpu_id__node(cpu, NULL);
		TEST_ASSERT_VAL("Node map - Node ID doesn't match",
				cpu__get_node(cpu) == id.node);
		TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
		TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1);
		TEST_ASSERT_VAL("Node map - Core is set", id.core == -1);
		TEST_ASSERT_VAL("Node map - CPU is set", id.cpu.cpu == -1);
		TEST_ASSERT_VAL("Node map - Thread IDX is set", id.thread_idx == -1);
	}
	perf_session__delete(session);

	return 0;
}

static int test__session_topology(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
	char path[PATH_MAX];
	struct perf_cpu_map *map;
	int ret = TEST_FAIL;

	TEST_ASSERT_VAL("can't get templ file", !get_temp(path));

	pr_debug("templ file: %s\n", path);

	if (session_write_header(path))
		goto free_path;

	map = perf_cpu_map__new_online_cpus();
	if (map == NULL) {
		pr_debug("failed to get system cpumap\n");
		goto free_path;
	}

	ret = check_cpu_topology(path, map);
	perf_cpu_map__put(map);

free_path:
	unlink(path);
	return ret;
}

DEFINE_SUITE("Session topology", session_topology);
