/*
 * Copyright 2012, Linaro
 *
 * This file is part of PowerTOP
 *
 * This program file is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; version 2 of the License.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program in a file named COPYING; if not, write to the
 * Free Software Foundation, Inc,
 * 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 * or just google for it.
 *
 * Authors:
 *	Rajagopal Venkat <rajagopal.venkat@linaro.org>
 */

#include <iostream>
#include <fstream>

#include <dirent.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include "device.h"
#include "devfreq.h"
#include "../display.h"
#include "../cpu/cpu.h"
#include "../report/report.h"
#include "../report/report-maker.h"

static bool is_enabled = true;

static vector<class devfreq *> all_devfreq;

devfreq::devfreq(const char* dpath): device()
{
	strncpy(dir_name, dpath, sizeof(dir_name));
}

uint64_t devfreq::parse_freq_time(char* pchr)
{
	char *cptr, *pptr = pchr;
	uint64_t ctime;

	cptr = strtok(pchr, " :");
	while (cptr != NULL) {
		cptr = strtok(NULL, " :");
		if (cptr )
			pptr = cptr;
	}

	ctime = strtoull(pptr, NULL, 10);
	return ctime;
}

void devfreq::process_time_stamps()
{
	unsigned int i;
	uint64_t active_time = 0;

	sample_time = (1000000.0 * (stamp_after.tv_sec - stamp_before.tv_sec))
			+ ((stamp_after.tv_usec - stamp_before.tv_usec) );

	for (i=0; i < dstates.size()-1; i++) {
		struct frequency *state = dstates[i];
		state->time_after = 1000 * (state->time_after - state->time_before);
		active_time += state->time_after;
	}
	/* Compute idle time for the device */
	dstates[i]->time_after = sample_time - active_time;
}

void devfreq::add_devfreq_freq_state(uint64_t freq, uint64_t time)
{
	struct frequency *state;

	state = new(std::nothrow) struct frequency;
	if (!state)
		return;

	memset(state, 0, sizeof(*state));
	dstates.push_back(state);

	state->freq = freq;
	if (freq == 0)
		strcpy(state->human_name, "Idle");
	else
		hz_to_human(freq, state->human_name);
	state->time_before = time;
}

void devfreq::update_devfreq_freq_state(uint64_t freq, uint64_t time)
{
	unsigned int i;
	struct frequency *state = NULL;

	for(i=0; i < dstates.size(); i++) {
		if (freq == dstates[i]->freq)
			state = dstates[i];
	}

	if (state == NULL) {
		add_devfreq_freq_state(freq, time);
		return;
	}

	state->time_after = time;
}

void devfreq::parse_devfreq_trans_stat(char *dname)
{
	ifstream file;
	char filename[256];

	sprintf(filename, "/sys/class/devfreq/%s/trans_stat", dir_name);
	file.open(filename);

	if (file) {
		char line[1024];
		char *c;

		while (file) {
			uint64_t freq;
			uint64_t time;
			char *pchr;

			memset(line, 0, sizeof(line));
			file.getline(line, sizeof(line));

			pchr = strchr(line, '*');
			pchr = (pchr != NULL) ? pchr+1 : line;

			freq = strtoull(pchr, &c, 10);
			if (!freq)
				continue;

			time = parse_freq_time(pchr);
			update_devfreq_freq_state(freq, time);
		}
	}
	file.close();
}

void devfreq::start_measurement(void)
{
	unsigned int i;
	ifstream file;

	for (i=0; i < dstates.size(); i++)
		delete dstates[i];
	dstates.resize(0);
	sample_time = 0;

	gettimeofday(&stamp_before, NULL);
	parse_devfreq_trans_stat(dir_name);
	/* add device idle state */
	update_devfreq_freq_state(0, 0);
}

void devfreq::end_measurement(void)
{
	parse_devfreq_trans_stat(dir_name);
	gettimeofday(&stamp_after, NULL);
	process_time_stamps();
}

double devfreq::power_usage(struct result_bundle *result, struct parameter_bundle *bundle)
{
	return 0;
}

double devfreq::utilization(void)
{
	return 0;
}

void devfreq::fill_freq_utilization(unsigned int idx, char *buf)
{
	buf[0] = 0;

	if (idx < dstates.size() && dstates[idx]) {
		struct frequency *state = dstates[idx];
		sprintf(buf, " %5.1f%% ", percentage(1.0 * state->time_after / sample_time));
	}
}

void devfreq::fill_freq_name(unsigned int idx, char *buf)
{
	buf[0] = 0;

	if (idx < dstates.size() && dstates[idx]) {
		sprintf(buf, "%-15s", dstates[idx]->human_name);
	}
}

void start_devfreq_measurement(void)
{
	unsigned int i;

	for (i=0; i<all_devfreq.size(); i++)
		all_devfreq[i]->start_measurement();
}

void end_devfreq_measurement(void)
{
	unsigned int i;

	for (i=0; i<all_devfreq.size(); i++)
		all_devfreq[i]->end_measurement();
}

static void devfreq_dev_callback(const char *d_name)
{
	devfreq *df = new(std::nothrow) class devfreq(d_name);
	if (df)
		all_devfreq.push_back(df);
}

void create_all_devfreq_devices(void)
{
	DIR *dir;
	std::string p = "/sys/class/devfreq/";
	dir = opendir(p.c_str());
	if (dir == NULL) {
		is_enabled = false;
		return;
	}

	callback fn = &devfreq_dev_callback;
	process_directory(p.c_str(), fn);
}

void initialize_devfreq(void)
{
	if (is_enabled)
		create_tab("Device Freq stats", _("Device Freq stats"));
}

void display_devfreq_devices(void)
{
	unsigned int i, j;
	WINDOW *win;
	char fline[1024];
	char buf[128];

	win = get_ncurses_win("Device Freq stats");
        if (!win)
                return;

        wclear(win);
        wmove(win, 2,0);

	if (!is_enabled) {
		wprintw(win, _(" Devfreq is not enabled"));
		return;
	}

	if (!all_devfreq.size()) {
		wprintw(win, _(" No devfreq devices available"));
		return;
	}

	for (i=0; i<all_devfreq.size(); i++) {

		class devfreq *df = all_devfreq[i];
		wprintw(win, "\n%s\n", df->device_name());

		for(j=0; j < df->dstates.size(); j++) {
			memset(fline, 0, sizeof(fline));
			strcpy(fline, "\t");
			df->fill_freq_name(j, buf);
			strcat(fline, buf);
			df->fill_freq_utilization(j, buf);
			strcat(fline, buf);
			strcat(fline, "\n");
			wprintw(win, fline);
		}
		wprintw(win, "\n");
	}
}

void report_devfreq_devices(void)
{

	char buffer[512];
	unsigned int i, j;

	if (!is_enabled) {
		return;
	}

	report.begin_section(SECTION_DEVFREQ);
	report.add_header("Device Frequency Report");

	report.begin_table(TABLE_WIDE);
	if (!all_devfreq.size()) {
		report.begin_row();
		report.add(" No devfreq devices available");
		return;
	}

	for (i = 0; i < all_devfreq.size(); i++) {
		buffer[0] = 0;
		class devfreq *df = all_devfreq[i];

		report.begin_row();
		report.begin_cell(CELL_CPU_PSTATE_HEADER);
		report.addf("%s", df->device_name());

		for (j = 0; j < df->dstates.size(); j++) {
			report.begin_row();
			report.begin_cell(CELL_CPU_STATE_VALUE);
			df->fill_freq_name(j, buffer);
			report.add(buffer);
			report.begin_cell(CELL_CPU_STATE_VALUE);
			df->fill_freq_utilization(j, buffer);
			report.add(buffer);
		}
	}
}

void clear_all_devfreq()
{
	unsigned int i, j;

	for (i=0; i < all_devfreq.size(); i++) {
		class devfreq *df = all_devfreq[i];

		for(j=0; j < df->dstates.size(); j++)
			delete df->dstates[j];

		df->dstates.resize(0);
		delete df;
	}
	all_devfreq.clear();
}
