/************************* INCLUDES *********************************/
#include <cstring>
#include <cfloat>
#include <limits>
#include <algorithm>
#include <string>

using namespace std;

#include "vtr_assert.h"

#include "PowerSpicedComponent.h"

bool sorter_PowerCallibSize(PowerCallibSize * a, PowerCallibSize * b);
bool sorter_PowerCallibInputs(PowerCallibInputs * a, PowerCallibInputs * b);

PowerCallibInputs::PowerCallibInputs(PowerSpicedComponent * parent_,
		float inputs) :
		parent(parent_), num_inputs(inputs), sorted(false), done_callibration(
				false) {

	/* Add min/max bounding entries */
	add_size(0);
	add_size(std::numeric_limits<float>::max());
}

void PowerCallibInputs::add_size(float transistor_size, float power) {
	PowerCallibSize * entry = new PowerCallibSize(transistor_size, power);
	entries.push_back(entry);
	sorted = false;
}

bool sorter_PowerCallibSize(PowerCallibSize * a, PowerCallibSize * b) {
	return a->transistor_size < b->transistor_size;
}

void PowerCallibInputs::sort_me() {
	sort(entries.begin(), entries.end(), sorter_PowerCallibSize);
	sorted = true;
}

void PowerCallibInputs::callibrate() {
	VTR_ASSERT(entries.size() >= 2);

	for (vector<PowerCallibSize*>::iterator it = entries.begin() + 1;
			it != entries.end() - 1; it++) {
		float est_power = parent->component_usage(num_inputs,
				(*it)->transistor_size);
		(*it)->factor = (*it)->power / est_power;
	}

	/* Set min-value placeholder */
	entries[0]->factor = entries[1]->factor;

	/* Set max-value placeholder */
	entries[entries.size() - 1]->factor = entries[entries.size() - 2]->factor;

	done_callibration = true;
}

PowerCallibSize * PowerCallibInputs::get_entry_bound(bool lower,
		float transistor_size) {
	PowerCallibSize * prev = entries[0];

	VTR_ASSERT(sorted);
	for (vector<PowerCallibSize*>::iterator it = entries.begin() + 1;
			it != entries.end(); it++) {
		if ((*it)->transistor_size > transistor_size) {
			if (lower)
				return prev;
			else
				return *it;
		}
		prev = *it;
	}
	return NULL;
}

PowerSpicedComponent::PowerSpicedComponent(std::string component_name,
		float (*usage_fn)(int num_inputs, float transistor_size)) {
	name = component_name;
	component_usage = usage_fn;

	/* Always pad with a high and low entry */
	add_entry(0);
//	add_entry(std::numeric_limits<int>::max());
	add_entry(1000000000);

	done_callibration = false;
	sorted = true;
}

PowerCallibInputs * PowerSpicedComponent::add_entry(int num_inputs) {
	PowerCallibInputs * entry = new PowerCallibInputs(this, num_inputs);
	entries.push_back(entry);
	return entry;
}

PowerCallibInputs * PowerSpicedComponent::get_entry(int num_inputs) {
	vector<PowerCallibInputs*>::iterator it;

	for (it = entries.begin(); it != entries.end(); it++) {
		if ((*it)->num_inputs == num_inputs) {
			break;
		}
	}

	if (it == entries.end()) {
		return add_entry(num_inputs);
	} else {
		return *it;
	}
}

PowerCallibInputs * PowerSpicedComponent::get_entry_bound(bool lower,
		int num_inputs) {
	PowerCallibInputs * prev = entries[0];

	VTR_ASSERT(sorted);
	for (vector<PowerCallibInputs*>::iterator it = entries.begin() + 1;
			it != entries.end(); it++) {
		if ((*it)->num_inputs > num_inputs) {
			if (lower) {
				if (prev == entries[0])
					return NULL;
				else
					return prev;
			} else {
				if (*it == entries[entries.size() - 1])
					return NULL;
				else
					return *it;
			}
		}
		prev = *it;
	}
	return NULL;
}

void PowerSpicedComponent::add_data_point(int num_inputs, float transistor_size,
		float power) {
	VTR_ASSERT(!done_callibration);
	PowerCallibInputs * inputs_entry = get_entry(num_inputs);
	inputs_entry->add_size(transistor_size, power);
	sorted = false;
}

float PowerSpicedComponent::scale_factor(int num_inputs,
		float transistor_size) {

	PowerCallibInputs * inputs_lower;
	PowerCallibInputs * inputs_upper;

	PowerCallibSize * size_lower;
	PowerCallibSize * size_upper;

	float factor_lower = 0.;
	float factor_upper = 0.;
	float factor;

	float perc_upper;

	VTR_ASSERT(done_callibration);

	inputs_lower = get_entry_bound(true, num_inputs);
	inputs_upper = get_entry_bound(false, num_inputs);

	if (inputs_lower) {
		/* Interpolation of factor between sizes for lower # inputs */
		VTR_ASSERT(inputs_lower->done_callibration);
		size_lower = inputs_lower->get_entry_bound(true, transistor_size);
		size_upper = inputs_lower->get_entry_bound(false, transistor_size);

		perc_upper = (transistor_size - size_lower->transistor_size)
				/ (size_upper->transistor_size - size_lower->transistor_size);
		factor_lower = perc_upper * size_upper->factor
				+ (1 - perc_upper) * size_lower->factor;
	}

	if (inputs_upper) {
		/* Interpolation of factor between sizes for upper # inputs */
		VTR_ASSERT(inputs_upper->done_callibration);
		size_lower = inputs_upper->get_entry_bound(true, transistor_size);
		size_upper = inputs_upper->get_entry_bound(false, transistor_size);

		perc_upper = (transistor_size - size_lower->transistor_size)
				/ (size_upper->transistor_size - size_lower->transistor_size);
		factor_upper = perc_upper * size_upper->factor
				+ (1 - perc_upper) * size_lower->factor;
	}

	if (!inputs_lower) {
		factor = factor_upper;
	} else if (!inputs_upper) {
		factor = factor_lower;
	} else {
		/* Interpolation of factor between inputs */
		perc_upper =
				((float) (num_inputs - inputs_lower->num_inputs))
						/ ((float) (inputs_upper->num_inputs
								- inputs_lower->num_inputs));
		factor = perc_upper * factor_upper + (1 - perc_upper) * factor_lower;
	}
	return factor;

}

bool sorter_PowerCallibInputs(PowerCallibInputs * a, PowerCallibInputs * b) {
	return a->num_inputs < b->num_inputs;
}

void PowerSpicedComponent::sort_me(void) {
	sort(entries.begin(), entries.end(), sorter_PowerCallibInputs);

	for (vector<PowerCallibInputs*>::iterator it = entries.begin();
			it != entries.end(); it++) {
		(*it)->sort_me();
	}
	sorted = true;
}

void PowerSpicedComponent::callibrate(void) {
	sort_me();

	for (vector<PowerCallibInputs*>::iterator it = entries.begin();
			it != entries.end(); it++) {
		(*it)->callibrate();
	}
	done_callibration = true;
}

bool PowerSpicedComponent::is_done_callibration(void) {
	return done_callibration;
}

void PowerSpicedComponent::print(FILE * fp) {
	fprintf(fp, "%s\n", name.c_str());
	for (vector<PowerCallibInputs*>::iterator it = entries.begin() + 1;
			it != entries.end() - 1; it++) {
		fprintf(fp, "Num Inputs: %d\n", (*it)->num_inputs);
		for (vector<PowerCallibSize*>::iterator it2 = (*it)->entries.begin()
				+ 1; it2 != (*it)->entries.end() - 1; it2++) {
			fprintf(fp, "  Transistor Size: %6f Factor: %3f\n",
					(*it2)->transistor_size, (*it2)->factor);
		}
	}
}
