// 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 "target.h"
#include <linux/err.h>
#include "dwarf-regs.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,
	};
	struct target target = {};

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

	session->evlist = evlist__new_default(&target, /*sample_callchains=*/false);
	TEST_ASSERT_VAL("can't get evlist", session->evlist);
	evlist__set_session(session->evlist, session);

	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,
						    perf_data__fd(&data), true));

	evlist__put(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,
	};
	unsigned int i;
	struct aggr_cpu_id id;
	struct perf_cpu cpu;
	struct perf_env *env;
	uint16_t e_machine;

	session = perf_session__new(&data, NULL);
	TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
	env = perf_session__env(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.
	 */
	e_machine = perf_env__e_machine(env, NULL);

	if (!env->cpu && e_machine != EM_S390 && e_machine != EM_AARCH64)
		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 (e_machine == EM_PPC64) {
		if (cpu__get_socket_id(perf_cpu_map__cpu(map, 0)) == -1)
			return TEST_SKIP;
	}

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

	for (i = 0; i < (unsigned int)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,
			 env->cpu[i].core_id,
			 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",
			env->cpu[cpu.cpu].core_id == id.core);
		TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match",
			env->cpu[cpu.cpu].socket_id == id.socket);

		TEST_ASSERT_VAL("Cpu map - Die ID doesn't match",
			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",
			env->cpu[cpu.cpu].core_id == id.core);

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

		TEST_ASSERT_VAL("Core map - Die ID doesn't match",
			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",
			env->cpu[cpu.cpu].socket_id == id.socket);

		TEST_ASSERT_VAL("Die map - Die ID doesn't match",
			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",
			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);
