/*
 * Copyright (c) 2011 Anssi Hannula
 *
 * 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:
 *	Anssi Hannula <anssi.hannula@iki.fi>
 */
#include "measurement.h"
#include "sysfs.h"
#include "../lib.h"
#include <string.h>
#include <stdio.h>

sysfs_power_meter::sysfs_power_meter(const char *power_supply_name)
{
	rate = 0.0;
	capacity = 0.0;
	strncpy(name, power_supply_name, sizeof(name));
}

bool sysfs_power_meter::get_sysfs_attr(const char *attribute, int *value)
{
	char filename[4096];
	bool ok;

	snprintf(filename, sizeof(filename), "/sys/class/power_supply/%s/%s", name, attribute);
	*value = read_sysfs(filename, &ok);

	return ok;
}

bool sysfs_power_meter::is_present()
{
	int present = 0;

	if (!get_sysfs_attr("present", &present))
		return true; /* assume always present */

	return present;
}

double sysfs_power_meter::get_voltage()
{
	int voltage;

	if (!get_sysfs_attr("voltage_now", &voltage))
		return -1.0;

	/* µV to V */
	return voltage / 1000000.0;
}

bool sysfs_power_meter::set_rate_from_power()
{
	int power;

	if (!get_sysfs_attr("power_now", &power))
		return false;

	/* µW to W */
	rate = power / 1000000.0;
	return true;
}

bool sysfs_power_meter::set_rate_from_current(double voltage)
{
	int current;

	if (!get_sysfs_attr("current_now", &current))
		return false;

	/* current: µA
	 * voltage: V
	 * rate: W */
	rate = (current / 1000000.0) * voltage;
	return true;
}

bool sysfs_power_meter::set_capacity_from_energy()
{
	int energy;

	if (!get_sysfs_attr("energy_now", &energy))
		return false;

	/* µWh to J */
	capacity = energy / 1000000.0 * 3600.0;
	return true;
}

bool sysfs_power_meter::set_capacity_from_charge(double voltage)
{
	int charge;

	if (!get_sysfs_attr("charge_now", &charge))
		return false;

	/* charge: µAh
	 * voltage: V
	 * capacity: J */
	capacity = (charge / 1000000.0) * voltage * 3600.0;
	return true;
}

void sysfs_power_meter::measure()
{
	bool got_rate = false;
	bool got_capacity = false;

	rate = 0.0;
	capacity = 0.0;

	if (!is_present())
		return;
	if (read_sysfs_string("/sys/class/power_supply/%s/status", name) != "Discharging")
		return;

	got_rate = set_rate_from_power();
	got_capacity = set_capacity_from_energy();

	if (!got_rate || !got_capacity) {
		double voltage = get_voltage();
		if (voltage < 0.0)
			return;
		if (!got_rate)
			set_rate_from_current(voltage);
		if (!got_capacity)
			set_capacity_from_charge(voltage);
	}
}


void sysfs_power_meter::end_measurement(void)
{
	measure();
}

void sysfs_power_meter::start_measurement(void)
{
	/* Battery state is generally a lagging indication, lets only measure at the end */
}
