/*
 * 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>

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

#include "lib.h"

#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>
#ifndef DISABLE_I18N
#include <libintl.h>
#endif
#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"));

#ifndef DISABLE_NCURSES
	while (mbstowcs(NULL,buffer,0) < len)
		strcat(buffer, " ");
#endif
}


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

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