/*
 * sysfs.c sysfs ABI access functions for TMON program
 *
 * Copyright (C) 2013 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 or later as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Author: Jacob Pan <jacob.jun.pan@linux.intel.com>
 *
 */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
#include <libintl.h>
#include <limits.h>
#include <ctype.h>
#include <time.h>
#include <syslog.h>
#include <sys/time.h>
#include <errno.h>

#include "tmon.h"

struct tmon_platform_data ptdata;
const char *trip_type_name[] = {
	"critical",
	"hot",
	"passive",
	"active",
};

int sysfs_set_ulong(char *path, char *filename, unsigned long val)
{
	FILE *fd;
	int ret = -1;
	char filepath[PATH_MAX + 2]; /* NUL and '/' */

	snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);

	fd = fopen(filepath, "w");
	if (!fd) {
		syslog(LOG_ERR, "Err: open %s: %s\n", __func__, filepath);
		return ret;
	}
	ret = fprintf(fd, "%lu", val);
	fclose(fd);

	return 0;
}

/* history of thermal data, used for control algo */
#define NR_THERMAL_RECORDS 3
struct thermal_data_record trec[NR_THERMAL_RECORDS];
int cur_thermal_record; /* index to the trec array */

static int sysfs_get_ulong(char *path, char *filename, unsigned long *p_ulong)
{
	FILE *fd;
	int ret = -1;
	char filepath[PATH_MAX + 2]; /* NUL and '/' */

	snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);

	fd = fopen(filepath, "r");
	if (!fd) {
		syslog(LOG_ERR, "Err: open %s: %s\n", __func__, filepath);
		return ret;
	}
	ret = fscanf(fd, "%lu", p_ulong);
	fclose(fd);

	return 0;
}

static int sysfs_get_string(char *path, char *filename, char *str)
{
	FILE *fd;
	int ret = -1;
	char filepath[PATH_MAX + 2]; /* NUL and '/' */

	snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);

	fd = fopen(filepath, "r");
	if (!fd) {
		syslog(LOG_ERR, "Err: open %s: %s\n", __func__, filepath);
		return ret;
	}
	ret = fscanf(fd, "%256s", str);
	fclose(fd);

	return ret;
}

/* get states of the cooling device instance */
static int probe_cdev(struct cdev_info *cdi, char *path)
{
	sysfs_get_string(path, "type", cdi->type);
	sysfs_get_ulong(path, "max_state",  &cdi->max_state);
	sysfs_get_ulong(path, "cur_state", &cdi->cur_state);

	syslog(LOG_INFO, "%s: %s: type %s, max %lu, curr %lu inst %d\n",
		__func__, path,
		cdi->type, cdi->max_state, cdi->cur_state, cdi->instance);

	return 0;
}

static int str_to_trip_type(char *name)
{
	int i;

	for (i = 0; i < NR_THERMAL_TRIP_TYPE; i++) {
		if (!strcmp(name, trip_type_name[i]))
			return i;
	}

	return -ENOENT;
}

/* scan and fill in trip point info for a thermal zone and trip point id */
static int get_trip_point_data(char *tz_path, int tzid, int tpid)
{
	char filename[256];
	char temp_str[256];
	int trip_type;

	if (tpid >= MAX_NR_TRIP)
		return -EINVAL;
	/* check trip point type */
	snprintf(filename, sizeof(filename), "trip_point_%d_type", tpid);
	sysfs_get_string(tz_path, filename, temp_str);
	trip_type = str_to_trip_type(temp_str);
	if (trip_type < 0) {
		syslog(LOG_ERR, "%s:%s no matching type\n", __func__, temp_str);
		return -ENOENT;
	}
	ptdata.tzi[tzid].tp[tpid].type = trip_type;
	syslog(LOG_INFO, "%s:tz:%d tp:%d:type:%s type id %d\n", __func__, tzid,
		tpid, temp_str, trip_type);

	/* TODO: check attribute */

	return 0;
}

/* return instance id for file format such as trip_point_4_temp */
static int get_instance_id(char *name, int pos, int skip)
{
	char *ch;
	int i = 0;

	ch = strtok(name, "_");
	while (ch != NULL) {
		++i;
		syslog(LOG_INFO, "%s:%s:%s:%d", __func__, name, ch, i);
		ch = strtok(NULL, "_");
		if (pos == i)
			return atol(ch + skip);
	}

	return -1;
}

/* Find trip point info of a thermal zone */
static int find_tzone_tp(char *tz_name, char *d_name, struct tz_info *tzi,
			int tz_id)
{
	int tp_id;
	unsigned long temp_ulong;

	if (strstr(d_name, "trip_point") &&
		strstr(d_name, "temp")) {
		/* check if trip point temp is non-zero
		 * ignore 0/invalid trip points
		 */
		sysfs_get_ulong(tz_name, d_name, &temp_ulong);
		if (temp_ulong < MAX_TEMP_KC) {
			tzi->nr_trip_pts++;
			/* found a valid trip point */
			tp_id = get_instance_id(d_name, 2, 0);
			syslog(LOG_DEBUG, "tzone %s trip %d temp %lu tpnode %s",
				tz_name, tp_id, temp_ulong, d_name);
			if (tp_id < 0 || tp_id >= MAX_NR_TRIP) {
				syslog(LOG_ERR, "Failed to find TP inst %s\n",
					d_name);
				return -1;
			}
			get_trip_point_data(tz_name, tz_id, tp_id);
			tzi->tp[tp_id].temp = temp_ulong;
		}
	}

	return 0;
}

/* check cooling devices for binding info. */
static int find_tzone_cdev(struct dirent *nl, char *tz_name,
			struct tz_info *tzi, int tz_id, int cid)
{
	unsigned long trip_instance = 0;
	char cdev_name_linked[256];
	char cdev_name[PATH_MAX];
	char cdev_trip_name[PATH_MAX];
	int cdev_id;

	if (nl->d_type == DT_LNK) {
		syslog(LOG_DEBUG, "TZ%d: cdev: %s cid %d\n", tz_id, nl->d_name,
			cid);
		tzi->nr_cdev++;
		if (tzi->nr_cdev > ptdata.nr_cooling_dev) {
			syslog(LOG_ERR, "Err: Too many cdev? %d\n",
				tzi->nr_cdev);
			return -EINVAL;
		}
		/* find the link to real cooling device record binding */
		snprintf(cdev_name, sizeof(cdev_name) - 2, "%s/%s",
			 tz_name, nl->d_name);
		memset(cdev_name_linked, 0, sizeof(cdev_name_linked));
		if (readlink(cdev_name, cdev_name_linked,
				sizeof(cdev_name_linked) - 1) != -1) {
			cdev_id = get_instance_id(cdev_name_linked, 1,
						sizeof("device") - 1);
			syslog(LOG_DEBUG, "cdev %s linked to %s : %d\n",
				cdev_name, cdev_name_linked, cdev_id);
			tzi->cdev_binding |= (1 << cdev_id);

			/* find the trip point in which the cdev is binded to
			 * in this tzone
			 */
			snprintf(cdev_trip_name, sizeof(cdev_trip_name) - 1,
				"%s%s", nl->d_name, "_trip_point");
			sysfs_get_ulong(tz_name, cdev_trip_name,
					&trip_instance);
			/* validate trip point range, e.g. trip could return -1
			 * when passive is enabled
			 */
			if (trip_instance > MAX_NR_TRIP)
				trip_instance = 0;
			tzi->trip_binding[cdev_id] |= 1 << trip_instance;
			syslog(LOG_DEBUG, "cdev %s -> trip:%lu: 0x%lx %d\n",
				cdev_name, trip_instance,
				tzi->trip_binding[cdev_id],
				cdev_id);


		}
		return 0;
	}

	return -ENODEV;
}



/*****************************************************************************
 * Before calling scan_tzones, thermal sysfs must be probed to determine
 * the number of thermal zones and cooling devices.
 * We loop through each thermal zone and fill in tz_info struct, i.e.
 * ptdata.tzi[]
root@jacob-chiefriver:~# tree -d /sys/class/thermal/thermal_zone0
/sys/class/thermal/thermal_zone0
|-- cdev0 -> ../cooling_device4
|-- cdev1 -> ../cooling_device3
|-- cdev10 -> ../cooling_device7
|-- cdev11 -> ../cooling_device6
|-- cdev12 -> ../cooling_device5
|-- cdev2 -> ../cooling_device2
|-- cdev3 -> ../cooling_device1
|-- cdev4 -> ../cooling_device0
|-- cdev5 -> ../cooling_device12
|-- cdev6 -> ../cooling_device11
|-- cdev7 -> ../cooling_device10
|-- cdev8 -> ../cooling_device9
|-- cdev9 -> ../cooling_device8
|-- device -> ../../../LNXSYSTM:00/device:62/LNXTHERM:00
|-- power
`-- subsystem -> ../../../../class/thermal
*****************************************************************************/
static int scan_tzones(void)
{
	DIR *dir;
	struct dirent **namelist;
	char tz_name[256];
	int i, j, n, k = 0;

	if (!ptdata.nr_tz_sensor)
		return -1;

	for (i = 0; i <= ptdata.max_tz_instance; i++) {
		memset(tz_name, 0, sizeof(tz_name));
		snprintf(tz_name, 256, "%s/%s%d", THERMAL_SYSFS, TZONE, i);

		dir = opendir(tz_name);
		if (!dir) {
			syslog(LOG_INFO, "Thermal zone %s skipped\n", tz_name);
			continue;
		}
		/* keep track of valid tzones */
		n = scandir(tz_name, &namelist, 0, alphasort);
		if (n < 0)
			syslog(LOG_ERR, "scandir failed in %s",  tz_name);
		else {
			sysfs_get_string(tz_name, "type", ptdata.tzi[k].type);
			ptdata.tzi[k].instance = i;
			/* detect trip points and cdev attached to this tzone */
			j = 0; /* index for cdev */
			ptdata.tzi[k].nr_cdev = 0;
			ptdata.tzi[k].nr_trip_pts = 0;
			while (n--) {
				char *temp_str;

				if (find_tzone_tp(tz_name, namelist[n]->d_name,
							&ptdata.tzi[k], k))
					break;
				temp_str = strstr(namelist[n]->d_name, "cdev");
				if (!temp_str) {
					free(namelist[n]);
					continue;
				}
				if (!find_tzone_cdev(namelist[n], tz_name,
							&ptdata.tzi[k], i, j))
					j++; /* increment cdev index */
				free(namelist[n]);
			}
			free(namelist);
		}
		/*TODO: reverse trip points */
		closedir(dir);
		syslog(LOG_INFO, "TZ %d has %d cdev\n",	i,
			ptdata.tzi[k].nr_cdev);
		k++;
	}

	return 0;
}

static int scan_cdevs(void)
{
	DIR *dir;
	struct dirent **namelist;
	char cdev_name[256];
	int i, n, k = 0;

	if (!ptdata.nr_cooling_dev) {
		fprintf(stderr, "No cooling devices found\n");
		return 0;
	}
	for (i = 0; i <= ptdata.max_cdev_instance; i++) {
		memset(cdev_name, 0, sizeof(cdev_name));
		snprintf(cdev_name, 256, "%s/%s%d", THERMAL_SYSFS, CDEV, i);

		dir = opendir(cdev_name);
		if (!dir) {
			syslog(LOG_INFO, "Cooling dev %s skipped\n", cdev_name);
			/* there is a gap in cooling device id, check again
			 * for the same index.
			 */
			continue;
		}

		n = scandir(cdev_name, &namelist, 0, alphasort);
		if (n < 0)
			syslog(LOG_ERR, "scandir failed in %s",  cdev_name);
		else {
			sysfs_get_string(cdev_name, "type", ptdata.cdi[k].type);
			ptdata.cdi[k].instance = i;
			if (strstr(ptdata.cdi[k].type, ctrl_cdev)) {
				ptdata.cdi[k].flag |= CDEV_FLAG_IN_CONTROL;
				syslog(LOG_DEBUG, "control cdev id %d\n", i);
			}
			while (n--)
				free(namelist[n]);
			free(namelist);
		}
		closedir(dir);
		k++;
	}
	return 0;
}


int probe_thermal_sysfs(void)
{
	DIR *dir;
	struct dirent **namelist;
	int n;

	dir = opendir(THERMAL_SYSFS);
	if (!dir) {
		fprintf(stderr, "\nNo thermal sysfs, exit\n");
		return -1;
	}
	n = scandir(THERMAL_SYSFS, &namelist, 0, alphasort);
	if (n < 0)
		syslog(LOG_ERR, "scandir failed in thermal sysfs");
	else {
		/* detect number of thermal zones and cooling devices */
		while (n--) {
			int inst;

			if (strstr(namelist[n]->d_name, CDEV)) {
				inst = get_instance_id(namelist[n]->d_name, 1,
						sizeof("device") - 1);
				/* keep track of the max cooling device since
				 * there may be gaps.
				 */
				if (inst > ptdata.max_cdev_instance)
					ptdata.max_cdev_instance = inst;

				syslog(LOG_DEBUG, "found cdev: %s %d %d\n",
					namelist[n]->d_name,
					ptdata.nr_cooling_dev,
					ptdata.max_cdev_instance);
				ptdata.nr_cooling_dev++;
			} else if (strstr(namelist[n]->d_name, TZONE)) {
				inst = get_instance_id(namelist[n]->d_name, 1,
						sizeof("zone") - 1);
				if (inst > ptdata.max_tz_instance)
					ptdata.max_tz_instance = inst;

				syslog(LOG_DEBUG, "found tzone: %s %d %d\n",
					namelist[n]->d_name,
					ptdata.nr_tz_sensor,
					ptdata.max_tz_instance);
				ptdata.nr_tz_sensor++;
			}
			free(namelist[n]);
		}
		free(namelist);
	}
	syslog(LOG_INFO, "found %d tzone(s), %d cdev(s), target zone %d\n",
		ptdata.nr_tz_sensor, ptdata.nr_cooling_dev,
		target_thermal_zone);
	closedir(dir);

	if (!ptdata.nr_tz_sensor) {
		fprintf(stderr, "\nNo thermal zones found, exit\n\n");
		return -1;
	}

	ptdata.tzi = calloc(ptdata.max_tz_instance+1, sizeof(struct tz_info));
	if (!ptdata.tzi) {
		fprintf(stderr, "Err: allocate tz_info\n");
		return -1;
	}

	/* we still show thermal zone information if there is no cdev */
	if (ptdata.nr_cooling_dev) {
		ptdata.cdi = calloc(ptdata.max_cdev_instance + 1,
				sizeof(struct cdev_info));
		if (!ptdata.cdi) {
			free(ptdata.tzi);
			fprintf(stderr, "Err: allocate cdev_info\n");
			return -1;
		}
	}

	/* now probe tzones */
	if (scan_tzones())
		return -1;
	if (scan_cdevs())
		return -1;
	return 0;
}

/* convert sysfs zone instance to zone array index */
int zone_instance_to_index(int zone_inst)
{
	int i;

	for (i = 0; i < ptdata.nr_tz_sensor; i++)
		if (ptdata.tzi[i].instance == zone_inst)
			return i;
	return -ENOENT;
}

/* read temperature of all thermal zones */
int update_thermal_data()
{
	int i;
	int next_thermal_record = cur_thermal_record + 1;
	char tz_name[256];
	static unsigned long samples;

	if (!ptdata.nr_tz_sensor) {
		syslog(LOG_ERR, "No thermal zones found!\n");
		return -1;
	}

	/* circular buffer for keeping historic data */
	if (next_thermal_record >= NR_THERMAL_RECORDS)
		next_thermal_record = 0;
	gettimeofday(&trec[next_thermal_record].tv, NULL);
	if (tmon_log) {
		fprintf(tmon_log, "%lu ", ++samples);
		fprintf(tmon_log, "%3.1f ", p_param.t_target);
	}
	for (i = 0; i < ptdata.nr_tz_sensor; i++) {
		memset(tz_name, 0, sizeof(tz_name));
		snprintf(tz_name, 256, "%s/%s%d", THERMAL_SYSFS, TZONE,
			ptdata.tzi[i].instance);
		sysfs_get_ulong(tz_name, "temp",
				&trec[next_thermal_record].temp[i]);
		if (tmon_log)
			fprintf(tmon_log, "%lu ",
				trec[next_thermal_record].temp[i] / 1000);
	}
	cur_thermal_record = next_thermal_record;
	for (i = 0; i < ptdata.nr_cooling_dev; i++) {
		char cdev_name[256];
		unsigned long val;

		snprintf(cdev_name, 256, "%s/%s%d", THERMAL_SYSFS, CDEV,
			ptdata.cdi[i].instance);
		probe_cdev(&ptdata.cdi[i], cdev_name);
		val = ptdata.cdi[i].cur_state;
		if (val > 1000000)
			val = 0;
		if (tmon_log)
			fprintf(tmon_log, "%lu ", val);
	}

	if (tmon_log) {
		fprintf(tmon_log, "\n");
		fflush(tmon_log);
	}

	return 0;
}

void set_ctrl_state(unsigned long state)
{
	char ctrl_cdev_path[256];
	int i;
	unsigned long cdev_state;

	if (no_control)
		return;
	/* set all ctrl cdev to the same state */
	for (i = 0; i < ptdata.nr_cooling_dev; i++) {
		if (ptdata.cdi[i].flag & CDEV_FLAG_IN_CONTROL) {
			if (ptdata.cdi[i].max_state < 10) {
				strcpy(ctrl_cdev, "None.");
				return;
			}
			/* scale to percentage of max_state */
			cdev_state = state * ptdata.cdi[i].max_state/100;
			syslog(LOG_DEBUG,
				"ctrl cdev %d set state %lu scaled to %lu\n",
				ptdata.cdi[i].instance, state, cdev_state);
			snprintf(ctrl_cdev_path, 256, "%s/%s%d", THERMAL_SYSFS,
				CDEV, ptdata.cdi[i].instance);
			syslog(LOG_DEBUG, "ctrl cdev path %s", ctrl_cdev_path);
			sysfs_set_ulong(ctrl_cdev_path, "cur_state",
					cdev_state);
		}
	}
}

void get_ctrl_state(unsigned long *state)
{
	char ctrl_cdev_path[256];
	int ctrl_cdev_id = -1;
	int i;

	/* TODO: take average of all ctrl types. also consider change based on
	 * uevent. Take the first reading for now.
	 */
	for (i = 0; i < ptdata.nr_cooling_dev; i++) {
		if (ptdata.cdi[i].flag & CDEV_FLAG_IN_CONTROL) {
			ctrl_cdev_id = ptdata.cdi[i].instance;
			syslog(LOG_INFO, "ctrl cdev %d get state\n",
				ptdata.cdi[i].instance);
			break;
		}
	}
	if (ctrl_cdev_id == -1) {
		*state = 0;
		return;
	}
	snprintf(ctrl_cdev_path, 256, "%s/%s%d", THERMAL_SYSFS,
		CDEV, ctrl_cdev_id);
	sysfs_get_ulong(ctrl_cdev_path, "cur_state", state);
}

void free_thermal_data(void)
{
	free(ptdata.tzi);
	free(ptdata.cdi);
}
