// 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 "pmu.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));

	if (!perf_pmu__has_hybrid()) {
		session->evlist = evlist__new_default();
		TEST_ASSERT_VAL("can't get evlist", session->evlist);
	} else {
		struct parse_events_error err;

		session->evlist = evlist__new();
		TEST_ASSERT_VAL("can't get evlist", session->evlist);
		parse_events_error__init(&err);
		parse_events(session->evlist, "cpu_core/cycles/", &err);
		parse_events_error__exit(&err);
	}

	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;

	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;

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

	for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
		if (!cpu_map__has(map, i))
			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 core ID contains socket, die and core
	for (i = 0; i < map->nr; i++) {
		id = cpu_map__get_core(map, i, NULL);
		TEST_ASSERT_VAL("Core map - Core ID doesn't match",
			session->header.env.cpu[map->map[i]].core_id == id.core);

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

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

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

		TEST_ASSERT_VAL("Die map - Die ID doesn't match",
			session->header.env.cpu[map->map[i]].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 - Thread is set", id.thread == -1);
	}

	// Test that socket ID contains only socket
	for (i = 0; i < map->nr; i++) {
		id = cpu_map__get_socket(map, i, NULL);
		TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
			session->header.env.cpu[map->map[i]].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 - Thread is set", id.thread == -1);
	}

	// Test that node ID contains only node
	for (i = 0; i < map->nr; i++) {
		id = cpu_map__get_node(map, i, NULL);
		TEST_ASSERT_VAL("Node map - Node ID doesn't match",
			cpu__get_node(map->map[i]) == 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 - Thread is set", id.thread == -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(NULL);
	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);
