#include <cstdio>

#include "vtr_log.h"
#include "vtr_memory.h"

#include "vpr_types.h"
#include "globals.h"
#include "segment_stats.h"

/*************** Variables and defines local to this module ****************/

#define LONGLINE 0

/******************* Subroutine definitions ********************************/

void get_segment_usage_stats(std::vector<t_segment_inf>& segment_inf) {
    /* Computes statistics on the fractional utilization of segments by type    *
     * (index) and by length.  This routine needs a valid rr_graph, and a       *
     * completed routing.  Note that segments cut off by the end of the array   *
     * are counted as full-length segments (e.g. length 4 even if the last 2    *
     * units of wire were chopped off by the chip edge).                        */

    int length, max_segment_length, cost_index;
    int *seg_occ_by_length, *seg_cap_by_length; /* [0..max_segment_length] */
    int *seg_occ_by_type, *seg_cap_by_type;     /* [0..num_segment-1]      */
    float utilization;

    auto& device_ctx = g_vpr_ctx.device();
    auto& route_ctx = g_vpr_ctx.routing();

    max_segment_length = 0;
    for (size_t seg_type = 0; seg_type < segment_inf.size(); seg_type++) {
        if (segment_inf[seg_type].longline == false)
            max_segment_length = std::max(max_segment_length,
                                          segment_inf[seg_type].length);
    }

    seg_occ_by_length = (int*)vtr::calloc((max_segment_length + 1),
                                          sizeof(int));
    seg_cap_by_length = (int*)vtr::calloc((max_segment_length + 1),
                                          sizeof(int));

    seg_occ_by_type = (int*)vtr::calloc(segment_inf.size(), sizeof(int));
    seg_cap_by_type = (int*)vtr::calloc(segment_inf.size(), sizeof(int));

    for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) {
        if (device_ctx.rr_nodes[inode].type() == CHANX || device_ctx.rr_nodes[inode].type() == CHANY) {
            cost_index = device_ctx.rr_nodes[inode].cost_index();
            size_t seg_type = device_ctx.rr_indexed_data[cost_index].seg_index;

            if (!segment_inf[seg_type].longline)
                length = segment_inf[seg_type].length;
            else
                length = LONGLINE;

            seg_occ_by_length[length] += route_ctx.rr_node_route_inf[inode].occ();
            seg_cap_by_length[length] += device_ctx.rr_nodes[inode].capacity();
            seg_occ_by_type[seg_type] += route_ctx.rr_node_route_inf[inode].occ();
            seg_cap_by_type[seg_type] += device_ctx.rr_nodes[inode].capacity();
        }
    }

    VTR_LOG("\n");
    VTR_LOG("Segment usage by type (index): type utilization\n");
    VTR_LOG("                               ---- -----------\n");

    for (size_t seg_type = 0; seg_type < segment_inf.size(); seg_type++) {
        if (seg_cap_by_type[seg_type] != 0) {
            utilization = (float)seg_occ_by_type[seg_type] / (float)seg_cap_by_type[seg_type];
            VTR_LOG("                               %4d %11.3g\n", seg_type, utilization);
        }
    }

    VTR_LOG("\n");
    VTR_LOG("Segment usage by length: length utilization\n");
    VTR_LOG("                         ------ -----------\n");

    for (length = 1; length <= max_segment_length; length++) {
        if (seg_cap_by_length[length] != 0) {
            utilization = (float)seg_occ_by_length[length] / (float)seg_cap_by_length[length];
            VTR_LOG("                         %6d %11.3g\n", length, utilization);
        }
    }
    VTR_LOG("\n");

    if (seg_cap_by_length[LONGLINE] != 0) {
        utilization = (float)seg_occ_by_length[LONGLINE] / (float)seg_cap_by_length[LONGLINE];
        VTR_LOG("   longline                 %5.3g\n", utilization);
    }

    free(seg_occ_by_length);
    free(seg_cap_by_length);
    free(seg_occ_by_type);
    free(seg_cap_by_type);
}
