/************************* INCLUDES *********************************/
#include <cstring>
#include <cfloat>
#include <limits>
#include <algorithm>
#include <string>

#include "vtr_assert.h"

#include "vpr_error.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());
}

PowerCallibInputs::~PowerCallibInputs() {
    for (auto entry : entries) {
        delete entry;
    }
}

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 (std::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 (std::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 nullptr;
}

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

PowerSpicedComponent::~PowerSpicedComponent() {
    for (auto entry : entries) {
        delete entry;
    }
}

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) {
    std::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 (std::vector<PowerCallibInputs*>::iterator it = entries.begin() + 1;
         it != entries.end(); it++) {
        if ((*it)->num_inputs > num_inputs) {
            if (lower) {
                if (prev == entries[0])
                    return nullptr;
                else
                    return prev;
            } else {
                if (*it == entries[entries.size() - 1])
                    return nullptr;
                else
                    return *it;
            }
        }
        prev = *it;
    }
    return nullptr;
}

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

        if (size_lower && size_upper) {
            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;
        } else {
            VPR_FATAL_ERROR(VPR_ERROR_POWER, "Failed to interpolate transitor size");
        }
    }

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

        if (size_lower && size_upper) {
            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;
        } else {
            VPR_FATAL_ERROR(VPR_ERROR_POWER, "Failed to interpolate transitor size");
        }
    }

    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() {
    sort(entries.begin(), entries.end(), sorter_PowerCallibInputs);

    for (std::vector<PowerCallibInputs*>::iterator it = entries.begin();
         it != entries.end(); it++) {
        (*it)->sort_me();
    }
    sorted = true;
}

void PowerSpicedComponent::callibrate() {
    sort_me();

    for (std::vector<PowerCallibInputs*>::iterator it = entries.begin();
         it != entries.end(); it++) {
        (*it)->callibrate();
    }
    done_callibration = true;
}

bool PowerSpicedComponent::is_done_callibration() {
    return done_callibration;
}

void PowerSpicedComponent::print(FILE* fp) {
    fprintf(fp, "%s\n", name.c_str());
    for (std::vector<PowerCallibInputs*>::iterator it = entries.begin() + 1;
         it != entries.end() - 1; it++) {
        fprintf(fp, "Num Inputs: %d\n", (*it)->num_inputs);
        for (std::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);
        }
    }
}
