// SPDX-License-Identifier: GPL-2.0-only
/*
 *  (C) 2016 SUSE Software Solutions GmbH
 *           Thomas Renninger <trenn@suse.de>
 */

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

#include "powercap.h"

static 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;
}

static int sysfs_get_enabled(char *path, int *mode)
{
	int fd;
	char yes_no;

	*mode = 0;

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

	if (read(fd, &yes_no, 1) != 1) {
		close(fd);
		return -1;
	}

	if (yes_no == '1') {
		*mode = 1;
		return 0;
	} else if (yes_no == '0') {
		return 0;
	}
	return -1;
}

int powercap_get_enabled(int *mode)
{
	char path[SYSFS_PATH_MAX] = PATH_TO_POWERCAP "/intel-rapl/enabled";

	return sysfs_get_enabled(path, mode);
}

/*
 * Hardcoded, because rapl is the only powercap implementation
- * this needs to get more generic if more powercap implementations
 * should show up
 */
int powercap_get_driver(char *driver, int buflen)
{
	char file[SYSFS_PATH_MAX] = PATH_TO_RAPL;

	struct stat statbuf;

	if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) {
		driver = "";
		return -1;
	} else if (buflen > 10) {
		strcpy(driver, "intel-rapl");
		return 0;
	} else
		return -1;
}

enum powercap_get64 {
	GET_ENERGY_UJ,
	GET_MAX_ENERGY_RANGE_UJ,
	GET_POWER_UW,
	GET_MAX_POWER_RANGE_UW,
	MAX_GET_64_FILES
};

static const char *powercap_get64_files[MAX_GET_64_FILES] = {
	[GET_POWER_UW] = "power_uw",
	[GET_MAX_POWER_RANGE_UW] = "max_power_range_uw",
	[GET_ENERGY_UJ] = "energy_uj",
	[GET_MAX_ENERGY_RANGE_UJ] = "max_energy_range_uj",
};

static int sysfs_powercap_get64_val(struct powercap_zone *zone,
				      enum powercap_get64 which,
				      uint64_t *val)
{
	char file[SYSFS_PATH_MAX] = PATH_TO_POWERCAP "/";
	int ret;
	char buf[MAX_LINE_LEN];

	strcat(file, zone->sys_name);
	strcat(file, "/");
	strcat(file, powercap_get64_files[which]);

	ret = sysfs_read_file(file, buf, MAX_LINE_LEN);
	if (ret < 0)
		return ret;
	if (ret == 0)
		return -1;

	*val = strtoll(buf, NULL, 10);
	return 0;
}

int powercap_get_max_energy_range_uj(struct powercap_zone *zone, uint64_t *val)
{
	return sysfs_powercap_get64_val(zone, GET_MAX_ENERGY_RANGE_UJ, val);
}

int powercap_get_energy_uj(struct powercap_zone *zone, uint64_t *val)
{
	return sysfs_powercap_get64_val(zone, GET_ENERGY_UJ, val);
}

int powercap_get_max_power_range_uw(struct powercap_zone *zone, uint64_t *val)
{
	return sysfs_powercap_get64_val(zone, GET_MAX_POWER_RANGE_UW, val);
}

int powercap_get_power_uw(struct powercap_zone *zone, uint64_t *val)
{
	return sysfs_powercap_get64_val(zone, GET_POWER_UW, val);
}

int powercap_zone_get_enabled(struct powercap_zone *zone, int *mode)
{
	char path[SYSFS_PATH_MAX] = PATH_TO_POWERCAP;

	if ((strlen(PATH_TO_POWERCAP) + strlen(zone->sys_name)) +
	    strlen("/enabled") + 1 >= SYSFS_PATH_MAX)
		return -1;

	strcat(path, "/");
	strcat(path, zone->sys_name);
	strcat(path, "/enabled");

	return sysfs_get_enabled(path, mode);
}

int powercap_zone_set_enabled(struct powercap_zone *zone, int mode)
{
	/* To be done if needed */
	return 0;
}


int powercap_read_zone(struct powercap_zone *zone)
{
	struct dirent *dent;
	DIR *zone_dir;
	char sysfs_dir[SYSFS_PATH_MAX] = PATH_TO_POWERCAP;
	struct powercap_zone *child_zone;
	char file[SYSFS_PATH_MAX] = PATH_TO_POWERCAP;
	int i, ret = 0;
	uint64_t val = 0;

	strcat(sysfs_dir, "/");
	strcat(sysfs_dir, zone->sys_name);

	zone_dir = opendir(sysfs_dir);
	if (zone_dir == NULL)
		return -1;

	strcat(file, "/");
	strcat(file, zone->sys_name);
	strcat(file, "/name");
	sysfs_read_file(file, zone->name, MAX_LINE_LEN);
	if (zone->parent)
		zone->tree_depth = zone->parent->tree_depth + 1;
	ret = powercap_get_energy_uj(zone, &val);
	if (ret == 0)
		zone->has_energy_uj = 1;
	ret = powercap_get_power_uw(zone, &val);
	if (ret == 0)
		zone->has_power_uw = 1;

	while ((dent = readdir(zone_dir)) != NULL) {
		struct stat st;

		if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
			continue;

		if (stat(dent->d_name, &st) != 0 || !S_ISDIR(st.st_mode))
			if (fstatat(dirfd(zone_dir), dent->d_name, &st, 0) < 0)
				continue;

		if (strncmp(dent->d_name, "intel-rapl:", 11) != 0)
			continue;

		child_zone = calloc(1, sizeof(struct powercap_zone));
		if (child_zone == NULL)
			return -1;
		for (i = 0; i < POWERCAP_MAX_CHILD_ZONES; i++) {
			if (zone->children[i] == NULL) {
				zone->children[i] = child_zone;
				break;
			}
			if (i == POWERCAP_MAX_CHILD_ZONES - 1) {
				free(child_zone);
				fprintf(stderr, "Reached POWERCAP_MAX_CHILD_ZONES %d\n",
				       POWERCAP_MAX_CHILD_ZONES);
				return -1;
			}
		}
		strcpy(child_zone->sys_name, zone->sys_name);
		strcat(child_zone->sys_name, "/");
		strcat(child_zone->sys_name, dent->d_name);
		child_zone->parent = zone;
		if (zone->tree_depth >= POWERCAP_MAX_TREE_DEPTH) {
			fprintf(stderr, "Maximum zone hierarchy depth[%d] reached\n",
				POWERCAP_MAX_TREE_DEPTH);
			ret = -1;
			break;
		}
		powercap_read_zone(child_zone);
	}
	closedir(zone_dir);
	return ret;
}

struct powercap_zone *powercap_init_zones(void)
{
	int enabled;
	struct powercap_zone *root_zone;
	int ret;
	char file[SYSFS_PATH_MAX] = PATH_TO_RAPL "/enabled";

	ret = sysfs_get_enabled(file, &enabled);

	if (ret)
		return NULL;

	if (!enabled)
		return NULL;

	root_zone = calloc(1, sizeof(struct powercap_zone));
	if (!root_zone)
		return NULL;

	strcpy(root_zone->sys_name, "intel-rapl/intel-rapl:0");

	powercap_read_zone(root_zone);

	return root_zone;
}

/* Call function *f on the passed zone and all its children */

int powercap_walk_zones(struct powercap_zone *zone,
			int (*f)(struct powercap_zone *zone))
{
	int i, ret;

	if (!zone)
		return -1;

	ret = f(zone);
	if (ret)
		return ret;

	for (i = 0; i < POWERCAP_MAX_CHILD_ZONES; i++) {
		if (zone->children[i] != NULL)
			powercap_walk_zones(zone->children[i], f);
	}
	return 0;
}
