/*
 * Copyright 2010, Intel Corporation
 *
 * 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:
 *	Arjan van de Ven <arjan@linux.intel.com>
 *	Peter Anvin
 */
#include <map>
#include <string.h>
#include <iostream>
#include <utility>
#include <iostream>
#include <fstream>
#include <string>
#include <ctype.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#include "lib.h"

#ifndef HAVE_NO_PCI
extern "C" {
#include <pci/pci.h>
}
#endif

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <locale.h>
#include <libintl.h>
#include <limits>
#include <math.h>
#include <ncurses.h>

static int kallsyms_read = 0;

double percentage(double F)
{
	F = F * 100.0;
//	if (F > 100.0)
//		F = 100.0;
	if (F < 0.0)
		F = 0.0;
	return F;
}

char *hz_to_human(unsigned long hz, char *buffer, int digits)
{
	unsigned long long Hz;

	buffer[0] = 0;

	Hz = hz;

	/* default: just put the Number in */
	sprintf(buffer,"%9lli", Hz);

	if (Hz>1000) {
		if (digits == 2)
			sprintf(buffer, "%4lli MHz", (Hz+500)/1000);
		else
			sprintf(buffer, "%6lli MHz", (Hz+500)/1000);
	}

	if (Hz>1500000) {
		if (digits == 2)
			sprintf(buffer, "%4.2f GHz", (Hz+5000.0)/1000000);
		else
			sprintf(buffer, "%3.1f GHz", (Hz+5000.0)/1000000);
	}

	return buffer;
}

using namespace std;

map<unsigned long, string> kallsyms;

static void read_kallsyms(void)
{
	ifstream file;
	char line[1024];
	kallsyms_read = 1;

	file.open("/proc/kallsyms", ios::in);

	while (file) {
		char *c = NULL, *c2 = NULL;
		unsigned long address = 0;
		memset(line, 0, 1024);
		file.getline(line, 1024);
		c = strchr(line, ' ');
		if (!c)
			continue;
		*c = 0;
		c2 = c + 1;
		if (*c2) c2++;
		if (*c2) c2++;

		address = strtoull(line, NULL, 16);
		c = strchr(c2, '\t');
		if (c)
			*c = 0;
		if (address != 0)
			kallsyms[address] = c2;
	}
	file.close();
}

const char *kernel_function(uint64_t address)
{
	const char *c;
	if (!kallsyms_read)
		read_kallsyms();

	c = kallsyms[address].c_str();
	if (!c)
		return "";
	return c;
}

static int _max_cpu;
int get_max_cpu(void)
{
	return _max_cpu;
}

void set_max_cpu(int cpu)
{
	if (cpu > _max_cpu)
		_max_cpu = cpu;
}


void write_sysfs(const string &filename, const string &value)
{
	ofstream file;

	file.open(filename.c_str(), ios::out);
	if (!file)
		return;
	try
	{
		file << value;
		file.close();
	} catch (std::exception &exc) {
		return;
	}
}

int read_sysfs(const string &filename, bool *ok)
{
	ifstream file;
	int i;

	file.open(filename.c_str(), ios::in);
	if (!file) {
		if (ok)
			*ok = false;
		return 0;
	}
	try
	{
		file >> i;
		if (ok)
			*ok = true;
	} catch (std::exception &exc) {
		if (ok)
			*ok = false;
		i = 0;
	}
	file.close();
	return i;
}

string read_sysfs_string(const string &filename)
{
	ifstream file;
	char content[4096];
	char *c;

	file.open(filename.c_str(), ios::in);
	if (!file)
		return "";
	try
	{
		file.getline(content, 4096);
		file.close();
		c = strchr(content, '\n');
		if (c)
			*c = 0;
	} catch (std::exception &exc) {
		file.close();
		return "";
	}
	return content;
}

string read_sysfs_string(const char *format, const char *param)
{
	ifstream file;
	char content[4096];
	char *c;
	char filename[8192];


	snprintf(filename, 8191, format, param);

	file.open(filename, ios::in);
	if (!file)
		return "";
	try
	{
		file.getline(content, 4096);
		file.close();
		c = strchr(content, '\n');
		if (c)
			*c = 0;
	} catch (std::exception &exc) {
		file.close();
		return "";
	}
	return content;
}


void format_watts(double W, char *buffer, unsigned int len)
{
	buffer[0] = 0;
	char buf[32];

	sprintf(buffer, _("%7sW"), fmt_prefix(W, buf));

	if (W < 0.0001)
		sprintf(buffer, _("    0 mW"));

	while (mbstowcs(NULL,buffer,len) < len)
		strcat(buffer, " ");
}


#ifndef HAVE_NO_PCI
static struct pci_access *pci_access;

char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len)
{
	char *ret;

	buffer[0] = 0;

	if (!pci_access) {
		pci_access = pci_alloc();
		pci_init(pci_access);
	}

	ret = pci_lookup_name(pci_access, buffer, len, PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, vendor, device);

	return ret;
}

void end_pci_access(void)
{
	if (pci_access)
		pci_free_name_list(pci_access);
}

#else

char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len)
{
	return NULL;
}

void end_pci_access(void)
{
}

#endif /* HAVE_NO_PCI */

int utf_ok = -1;



/* pretty print numbers while limiting the precision */
char *fmt_prefix(double n, char *buf)
{
	static const char prefixes[] = "yzafpnum kMGTPEZY";
	char tmpbuf[16];
	int omag, npfx;
	char *p, *q, pfx, *c;
	int i;

	if (utf_ok == -1) {
		char *g;
		g = getenv("LANG");
		if (g && strstr(g, "UTF-8"))
			utf_ok = 1;
		else
			utf_ok = 0;
	}

	p = buf;

	*p = ' ';
	if (n < 0.0) {
		*p = '-';
		n = -n;
		p++;
	}

	snprintf(tmpbuf, sizeof tmpbuf, "%.2e", n);
	c = strchr(tmpbuf, 'e');
	if (!c) {
		sprintf(buf, "NaN");
		return buf;
	}
	omag = atoi(c + 1);

	npfx = ((omag + 27) / 3) - (27/3);
	omag = (omag + 27) % 3;

	q = tmpbuf;
	if (omag == 2)
		omag = -1;

	for (i = 0; i < 3; i++) {
		while (!isdigit(*q))
			q++;
		*p++ = *q++;
		if (i == omag)
			*p++ = '.';
	}
	*p++ = ' ';

	pfx = prefixes[npfx + 8];

	if (pfx == ' ') {
		/* do nothing */
	} else if (pfx == 'u' && utf_ok > 0) {
		strcpy(p, "µ");		/* Mu is a multibyte sequence */
		while (*p)
			p++;
	} else {
		*p++ = pfx;
	}
	*p = '\0';

	return buf;
}

static map<string, string> pretty_prints;
static int pretty_print_init = 0;

static void init_pretty_print(void)
{
	pretty_prints["[12] i8042"] = _("PS/2 Touchpad / Keyboard / Mouse");
	pretty_prints["ahci"] = _("SATA controller");
	pretty_prints["usb-device-8087-0020"] = _("Intel built in USB hub");
}


char *pretty_print(const char *str, char *buf, int len)
{
	const char *p;

	if (!pretty_print_init)
		init_pretty_print();

	p = pretty_prints[str].c_str();

	if (strlen(p) == 0)
		p = str;

	snprintf(buf, len,  "%s", p);

	if (len)
		buf[len - 1] = 0;
	return buf;
}

int equals(double a, double b)
{
	return fabs(a - b) <= std::numeric_limits<double>::epsilon();
}

void process_directory(const char *d_name, callback fn)
{
	struct dirent *entry;
	DIR *dir;
	dir = opendir(d_name);
	if (!dir)
		return;
	while (1) {
		entry = readdir(dir);
		if (!entry)
			break;
		if (entry->d_name[0] == '.')
			continue;
		if (strcmp(entry->d_name, "lo")==0)
			continue;

		fn(entry->d_name);
	}

	closedir(dir);
}

int get_user_input(char *buf, unsigned sz)
{
	fflush(stdout);
	echo();
	/* Upon successful completion, these functions return OK. Otherwise, they return ERR. */
	int ret = getnstr(buf, sz);
	noecho();
	fflush(stdout);
	/* to distinguish between getnstr error and empty line */
	return ret || strlen(buf);
}
