/*
 *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

#include "cpupower.h"
#include "cpupower_intern.h"

unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
{
	int fd;
	ssize_t numread;

	fd = open(path, O_RDONLY);
	if (fd == -1)
		return 0;

	numread = read(fd, buf, buflen - 1);
	if (numread < 1) {
		close(fd);
		return 0;
	}

	buf[numread] = '\0';
	close(fd);

	return (unsigned int) numread;
}

/*
 * Detect whether a CPU is online
 *
 * Returns:
 *     1 -> if CPU is online
 *     0 -> if CPU is offline
 *     negative errno values in error case
 */
int cpupower_is_cpu_online(unsigned int cpu)
{
	char path[SYSFS_PATH_MAX];
	int fd;
	ssize_t numread;
	unsigned long long value;
	char linebuf[MAX_LINE_LEN];
	char *endp;
	struct stat statbuf;

	snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu);

	if (stat(path, &statbuf) != 0)
		return 0;

	/*
	 * kernel without CONFIG_HOTPLUG_CPU
	 * -> cpuX directory exists, but not cpuX/online file
	 */
	snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu);
	if (stat(path, &statbuf) != 0)
		return 1;

	fd = open(path, O_RDONLY);
	if (fd == -1)
		return -errno;

	numread = read(fd, linebuf, MAX_LINE_LEN - 1);
	if (numread < 1) {
		close(fd);
		return -EIO;
	}
	linebuf[numread] = '\0';
	close(fd);

	value = strtoull(linebuf, &endp, 0);
	if (value > 1)
		return -EINVAL;

	return value;
}

/* returns -1 on failure, 0 on success */
static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *result)
{
	char linebuf[MAX_LINE_LEN];
	char *endp;
	char path[SYSFS_PATH_MAX];

	snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s",
			 cpu, fname);
	if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0)
		return -1;
	*result = strtol(linebuf, &endp, 0);
	if (endp == linebuf || errno == ERANGE)
		return -1;
	return 0;
}

static int __compare(const void *t1, const void *t2)
{
	struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1;
	struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2;
	if (top1->pkg < top2->pkg)
		return -1;
	else if (top1->pkg > top2->pkg)
		return 1;
	else if (top1->core < top2->core)
		return -1;
	else if (top1->core > top2->core)
		return 1;
	else if (top1->cpu < top2->cpu)
		return -1;
	else if (top1->cpu > top2->cpu)
		return 1;
	else
		return 0;
}

/*
 * Returns amount of cpus, negative on error, cpu_top must be
 * passed to cpu_topology_release to free resources
 *
 * Array is sorted after ->pkg, ->core, then ->cpu
 */
int get_cpu_topology(struct cpupower_topology *cpu_top)
{
	int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF);

	cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus);
	if (cpu_top->core_info == NULL)
		return -ENOMEM;
	cpu_top->pkgs = cpu_top->cores = 0;
	for (cpu = 0; cpu < cpus; cpu++) {
		cpu_top->core_info[cpu].cpu = cpu;
		cpu_top->core_info[cpu].is_online = cpupower_is_cpu_online(cpu);
		if(sysfs_topology_read_file(
			cpu,
			"physical_package_id",
			&(cpu_top->core_info[cpu].pkg)) < 0) {
			cpu_top->core_info[cpu].pkg = -1;
			cpu_top->core_info[cpu].core = -1;
			continue;
		}
		if(sysfs_topology_read_file(
			cpu,
			"core_id",
			&(cpu_top->core_info[cpu].core)) < 0) {
			cpu_top->core_info[cpu].pkg = -1;
			cpu_top->core_info[cpu].core = -1;
			continue;
		}
	}

	qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
	      __compare);

	/* Count the number of distinct pkgs values. This works
	   because the primary sort of the core_info struct was just
	   done by pkg value. */
	last_pkg = cpu_top->core_info[0].pkg;
	for(cpu = 1; cpu < cpus; cpu++) {
		if (cpu_top->core_info[cpu].pkg != last_pkg &&
				cpu_top->core_info[cpu].pkg != -1) {

			last_pkg = cpu_top->core_info[cpu].pkg;
			cpu_top->pkgs++;
		}
	}
	if (!(cpu_top->core_info[0].pkg == -1))
		cpu_top->pkgs++;

	/* Intel's cores count is not consecutively numbered, there may
	 * be a core_id of 3, but none of 2. Assume there always is 0
	 * Get amount of cores by counting duplicates in a package
	for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) {
		if (cpu_top->core_info[cpu].core == 0)
	cpu_top->cores++;
	*/
	return cpus;
}

void cpu_topology_release(struct cpupower_topology cpu_top)
{
	free(cpu_top.core_info);
}
