#include <cstdio>
using namespace std;

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

#include "vpr_types.h"
#include "vpr_error.h"

#include "globals.h"
#include "net_delay.h"
/***************** Types and defines local to this module ********************/
struct t_rc_node;

/* Linked list listing the children of an rc_node.                           *
 * child:  Pointer to an rc_node (child of the current node).                *
 * iswitch:  Index of the switch type used to connect to the child node.     *
 * next:   Pointer to the next linked_rc_edge in the linked list (allows     *
 *         you to get the next child of the current rc_node).                */
struct t_linked_rc_edge {
	t_rc_node *child;
	short iswitch;
	t_linked_rc_edge *next;
};


/* Structure describing one node in an RC tree (used to get net delays).     *
 * u.child_list:  Pointer to a linked list of linked_rc_edge.  Each one of   *
 *                the linked list entries gives a child of this node.        *
 * u.next:  Used only when this node is on the free list.  Gives the next    *
 *          node on the free list.                                           *
 * inode:  index (ID) of the rr_node that corresponds to this rc_node.       *
 * C_downstream:  Total downstream capacitance from this rc_node.  That is,  *
 *                the total C of the subtree rooted at the current node,     *
 *                including the C of the current node.                       *
 * Tdel:  Time delay for the signal to get from the net source to this node. *
 *        Includes the time to go through this node.                         */
struct t_rc_node {
	union {
		t_linked_rc_edge *child_list;
		t_rc_node *next;
	} u;
	int inode;
	float C_downstream;
	float Tdel;
};


/* Linked list of pointers to rc_nodes.                                      *
 * rc_node:  Pointer to an rc_node.                                          *
 * next:  Next list element.                                                 */
struct t_linked_rc_ptr {
	t_rc_node *rc_node;
	t_linked_rc_ptr *next;
};

/*********************** Subroutines local to this module ********************/

static t_rc_node *alloc_and_load_rc_tree(ClusterNetId net_id,
		t_rc_node ** rc_node_free_list_ptr,
		t_linked_rc_edge ** rc_edge_free_list_ptr,
		t_linked_rc_ptr * rr_node_to_rc_node);

static void add_to_rc_tree(t_rc_node * parent_rc, t_rc_node * child_rc,
		short iswitch, int inode, t_linked_rc_edge ** rc_edge_free_list_ptr);

static t_rc_node *alloc_rc_node(t_rc_node ** rc_node_free_list_ptr);

static void free_rc_node(t_rc_node * rc_node,
		t_rc_node ** rc_node_free_list_ptr);

static t_linked_rc_edge *alloc_linked_rc_edge(
		t_linked_rc_edge ** rc_edge_free_list_ptr);

static void free_linked_rc_edge(t_linked_rc_edge * rc_edge,
		t_linked_rc_edge ** rc_edge_free_list_ptr);

static float load_rc_tree_C(t_rc_node * rc_node);

static void load_rc_tree_T(t_rc_node * rc_node, float T_arrival);

static void load_one_net_delay(vtr::vector<ClusterNetId, float *> &net_delay, ClusterNetId net_id, t_linked_rc_ptr * rr_node_to_rc_node);

static void load_one_constant_net_delay(vtr::vector<ClusterNetId, float *> &net_delay, ClusterNetId net_id, float delay_value);

static void free_rc_tree(t_rc_node * rc_root,
		t_rc_node ** rc_node_free_list_ptr,
		t_linked_rc_edge ** rc_edge_free_list_ptr);

static void reset_rr_node_to_rc_node(t_linked_rc_ptr * rr_node_to_rc_node,
		ClusterNetId net_id);

static void free_rc_node_free_list(t_rc_node * rc_node_free_list);

static void free_rc_edge_free_list(t_linked_rc_edge * rc_edge_free_list);

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

/* Allocates space for the net_delay data structure   *
* [0..nets.size()-1][1..num_pins-1]. I chunk the data *
* to save space on large problems.                    */
vtr::vector<ClusterNetId, float *> alloc_net_delay(vtr::t_chunk *chunk_list_ptr){
	auto& cluster_ctx = g_vpr_ctx.clustering();
	vtr::vector<ClusterNetId, float *> net_delay; /* [0..nets.size()-1][1..num_pins-1] */

    auto nets = cluster_ctx.clb_nlist.nets();
	net_delay.resize(nets.size());

	for (auto net_id : nets) {
		float* tmp_ptr = (float *) vtr::chunk_malloc(cluster_ctx.clb_nlist.net_sinks(net_id).size() * sizeof(float), chunk_list_ptr);

		net_delay[net_id] = tmp_ptr - 1; /* [1..num_pins-1] */

        //Ensure the net delays are initialized with non-garbage values
		for (size_t ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ++ipin) {
            net_delay[net_id][ipin] = std::numeric_limits<float>::quiet_NaN();
        }
	}

	return (net_delay);
}

void free_net_delay(vtr::vector<ClusterNetId, float *> &net_delay,
		vtr::t_chunk *chunk_list_ptr){

	/* Frees the net_delay structure.  Assumes it was chunk allocated.          */

	net_delay.clear();
    vtr::free_chunk_memory(chunk_list_ptr);
}

void load_net_delay_from_routing(vtr::vector<ClusterNetId, float *> &net_delay) {

	/* This routine loads net_delay[0..nets.size()-1][1..num_pins-1].  Each entry   *
	 * is the Elmore delay from the net source to the appropriate sink.  Both    *
	 * the rr_graph and the routing traceback must be completely constructed     *
	 * before this routine is called, and the net_delay array must have been     *
	 * allocated.                                                                */
    auto& device_ctx = g_vpr_ctx.device();
	auto& cluster_ctx = g_vpr_ctx.clustering();

	t_rc_node *rc_node_free_list, *rc_root;
	t_linked_rc_edge *rc_edge_free_list;
	t_linked_rc_ptr *rr_node_to_rc_node; /* [0..device_ctx.rr_nodes.size()-1]  */

	rr_node_to_rc_node = (t_linked_rc_ptr *) vtr::calloc(device_ctx.rr_nodes.size(),
			sizeof(t_linked_rc_ptr));

	rc_node_free_list = nullptr;
	rc_edge_free_list = nullptr;

	for (auto net_id : cluster_ctx.clb_nlist.nets()) {
		if (cluster_ctx.clb_nlist.net_is_ignored(net_id)) {
			load_one_constant_net_delay(net_delay, net_id, 0.);
		} else {
			rc_root = alloc_and_load_rc_tree(net_id, &rc_node_free_list,
					&rc_edge_free_list, rr_node_to_rc_node);
			load_rc_tree_C(rc_root);
			load_rc_tree_T(rc_root, 0.);
			load_one_net_delay(net_delay, net_id, rr_node_to_rc_node);
			free_rc_tree(rc_root, &rc_node_free_list, &rc_edge_free_list);
			reset_rr_node_to_rc_node(rr_node_to_rc_node, net_id);
		}
	}

	free_rc_node_free_list(rc_node_free_list);
	free_rc_edge_free_list(rc_edge_free_list);
	free(rr_node_to_rc_node);
}

static t_rc_node *
alloc_and_load_rc_tree(ClusterNetId net_id, t_rc_node ** rc_node_free_list_ptr,
		t_linked_rc_edge ** rc_edge_free_list_ptr,
		t_linked_rc_ptr * rr_node_to_rc_node) {

	/* Builds a tree describing the routing of net inet.  Allocates all the data *
	 * and inserts all the connections in the tree.                              */

	t_rc_node *curr_rc, *prev_rc, *root_rc;
	t_trace *tptr;
	int inode;
	short iswitch;
	t_linked_rc_ptr *linked_rc_ptr;

    auto& route_ctx = g_vpr_ctx.routing();

	root_rc = alloc_rc_node(rc_node_free_list_ptr);
	tptr = route_ctx.trace[net_id].head;

	if (tptr == nullptr) {
		vpr_throw(VPR_ERROR_TIMING,__FILE__, __LINE__,
				"in alloc_and_load_rc_tree: Traceback for net %lu does not exist.\n", size_t(net_id));
	}

	inode = tptr->index;
	iswitch = tptr->iswitch;
	root_rc->inode = inode;
	root_rc->u.child_list = nullptr;
	rr_node_to_rc_node[inode].rc_node = root_rc;

	prev_rc = root_rc;
	tptr = tptr->next;

	while (tptr != nullptr) {
		inode = tptr->index;

		/* Is this node a "stitch-in" point to part of the existing routing or a   *
		 * new piece of routing along the current routing "arm?"                   */

		if (rr_node_to_rc_node[inode].rc_node == nullptr) { /* Part of current "arm" */
			curr_rc = alloc_rc_node(rc_node_free_list_ptr);
			add_to_rc_tree(prev_rc, curr_rc, iswitch, inode, rc_edge_free_list_ptr);
			rr_node_to_rc_node[inode].rc_node = curr_rc;
			prev_rc = curr_rc;

		} else if (iswitch == OPEN) { /* Connection to old stuff. */

			prev_rc = rr_node_to_rc_node[inode].rc_node;

		} else { /* SINK that this net has connected to more than once. */

			/* I can connect to a SINK node more than once in some weird architectures. *
			 * That means the routing isn't really a tree -- there is reconvergent      *
			 * fanout from two or more IPINs into one SINK.  I convert this structure   *
			 * into a true RC tree on the fly by creating a new rc_node each time I hit *
			 * the same sink.  This means I need to keep a linked list of the rc_nodes  *
			 * associated with the rr_node (inode) associated with that SINK.           */

			curr_rc = alloc_rc_node(rc_node_free_list_ptr);
			add_to_rc_tree(prev_rc, curr_rc, iswitch, inode, rc_edge_free_list_ptr);

			linked_rc_ptr = (t_linked_rc_ptr *) vtr::malloc(sizeof(t_linked_rc_ptr));
			linked_rc_ptr->next = rr_node_to_rc_node[inode].next;
			rr_node_to_rc_node[inode].next = linked_rc_ptr;
			linked_rc_ptr->rc_node = curr_rc;

			prev_rc = curr_rc;
		}
		iswitch = tptr->iswitch;
		tptr = tptr->next;
	}

	return (root_rc);
}

static void add_to_rc_tree(t_rc_node * parent_rc, t_rc_node * child_rc,
		short iswitch, int inode, t_linked_rc_edge ** rc_edge_free_list_ptr) {

	/* Adds child_rc to the child list of parent_rc, and sets the switch between *
	 * them to iswitch.  This routine also intitializes the child_rc properly    *
	 * and sets its node value to inode.                                         */

	t_linked_rc_edge *linked_rc_edge;

	linked_rc_edge = alloc_linked_rc_edge(rc_edge_free_list_ptr);

	linked_rc_edge->next = parent_rc->u.child_list;
	parent_rc->u.child_list = linked_rc_edge;

	linked_rc_edge->child = child_rc;
	linked_rc_edge->iswitch = iswitch;

	child_rc->u.child_list = nullptr;
	child_rc->inode = inode;
}

static t_rc_node *
alloc_rc_node(t_rc_node ** rc_node_free_list_ptr) {

	/* Allocates a new rc_node, from the free list if possible, from the free   *
	 * store otherwise.                                                         */

	t_rc_node *rc_node;

	rc_node = *rc_node_free_list_ptr;

	if (rc_node != nullptr) {
		*rc_node_free_list_ptr = rc_node->u.next;
	} else {
		rc_node = (t_rc_node *) vtr::malloc(sizeof(t_rc_node));
	}

	return (rc_node);
}

static void free_rc_node(t_rc_node * rc_node,
		t_rc_node ** rc_node_free_list_ptr) {

	/* Adds rc_node to the proper free list.          */

	rc_node->u.next = *rc_node_free_list_ptr;
	*rc_node_free_list_ptr = rc_node;
}

static t_linked_rc_edge *
alloc_linked_rc_edge(t_linked_rc_edge ** rc_edge_free_list_ptr) {

	/* Allocates a new linked_rc_edge, from the free list if possible, from the  *
	 * free store otherwise.                                                     */

	t_linked_rc_edge *linked_rc_edge;

	linked_rc_edge = *rc_edge_free_list_ptr;

	if (linked_rc_edge != nullptr) {
		*rc_edge_free_list_ptr = linked_rc_edge->next;
	} else {
		linked_rc_edge = (t_linked_rc_edge *) vtr::malloc(
				sizeof(t_linked_rc_edge));
	}

	return (linked_rc_edge);
}

static void free_linked_rc_edge(t_linked_rc_edge * rc_edge,
		t_linked_rc_edge ** rc_edge_free_list_ptr) {

	/* Adds the rc_edge to the rc_edge free list.                       */

	rc_edge->next = *rc_edge_free_list_ptr;
	*rc_edge_free_list_ptr = rc_edge;
}

static float load_rc_tree_C(t_rc_node * rc_node) {

	/* Does a post-order traversal of the rc tree to load each node's           *
	 * C_downstream with the proper sum of all the downstream capacitances.     *
	 * This routine calls itself recursively to perform the traversal.          */

	t_linked_rc_edge *linked_rc_edge;
	t_rc_node *child_node;
	int inode;
	short iswitch;
	float C, C_downstream;

    auto& device_ctx = g_vpr_ctx.device();

	linked_rc_edge = rc_node->u.child_list;
	inode = rc_node->inode;
	C = device_ctx.rr_nodes[inode].C();

	while (linked_rc_edge != nullptr) { /* For all children */
		iswitch = linked_rc_edge->iswitch;
		child_node = linked_rc_edge->child;
		C_downstream = load_rc_tree_C(child_node);

		if (!device_ctx.rr_switch_inf[iswitch].buffered())
			C += C_downstream;

		linked_rc_edge = linked_rc_edge->next;
	}

	rc_node->C_downstream = C;
	return (C);
}

static void load_rc_tree_T(t_rc_node * rc_node, float T_arrival) {

	/* This routine does a pre-order depth-first traversal of the rc tree to    *
	 * compute the Tdel to each node in the rc tree.  The T_arrival is the time *
	 * at which the signal hits the input to this node.  This routine calls     *
	 * itself recursively to perform the traversal.                             */

	float Tdel, Rmetal, Tchild;
	t_linked_rc_edge *linked_rc_edge;
	t_rc_node *child_node;
	short iswitch;
	int inode;

    auto& device_ctx = g_vpr_ctx.device();

	Tdel = T_arrival;
	inode = rc_node->inode;
	Rmetal = device_ctx.rr_nodes[inode].R();

	/* NB:  device_ctx.rr_nodes[inode].C gives the capacitance of this node, while          *
	 * rc_node->C_downstream gives the unbuffered downstream capacitance rooted *
	 * at this node, including the C of the node itself.  I want to multiply    *
	 * the C of this node by 0.5 Rmetal, since it's a distributed RC line.      *
	 * Hence 0.5 Rmetal * Cnode is a pessimistic estimate of delay (i.e. end to *
	 * end).  For the downstream capacitance rooted at this node (not including *
	 * the capacitance of the node itself), I assume it is, on average,         *
	 * connected halfway along the line, so I also multiply by 0.5 Rmetal.  To  *
	 * be totally pessimistic I would multiply the downstream part of the       *
	 * capacitance by Rmetal.  Play with this equation if you like.             */

	/* Rmetal is distributed so x0.5 */
	Tdel += 0.5 * rc_node->C_downstream * Rmetal;
	rc_node->Tdel = Tdel;

	/* Now expand the children of this node to load their Tdel values.       */

	linked_rc_edge = rc_node->u.child_list;

	while (linked_rc_edge != nullptr) { /* For all children */
		iswitch = linked_rc_edge->iswitch;
		child_node = linked_rc_edge->child;

		Tchild = Tdel + device_ctx.rr_switch_inf[iswitch].R * child_node->C_downstream;
		Tchild += device_ctx.rr_switch_inf[iswitch].Tdel; /* Intrinsic switch delay. */
		load_rc_tree_T(child_node, Tchild);

		linked_rc_edge = linked_rc_edge->next;
	}
}

/* Loads the net delay array for net inet.  The rc tree for that net must  *
* have already been completely built and loaded.                           */
static void load_one_net_delay(vtr::vector<ClusterNetId, float *> &net_delay, ClusterNetId net_id, t_linked_rc_ptr * rr_node_to_rc_node) {
	unsigned int ipin, inode;
	float Tmax;
	t_rc_node *rc_node;
	t_linked_rc_ptr *linked_rc_ptr, *next_ptr;

	auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& route_ctx = g_vpr_ctx.routing();

	for (ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++) {
		inode = route_ctx.net_rr_terminals[net_id][ipin];
		linked_rc_ptr = rr_node_to_rc_node[inode].next;
		rc_node = rr_node_to_rc_node[inode].rc_node;
		Tmax = rc_node->Tdel;

		/* If below only executes when one net connects several times to the      *
		 * same SINK.  In this case, I can't tell which net pin each connection   *
		 * to this SINK corresponds to (I can just choose arbitrarily).  To make  *
		 * sure the timing behaviour converges, I pessimistically set the delay   *
		 * for all of the connections to this SINK by this net to be the max. of  *
		 * the delays from this net to this SINK.  NB:  This code only occurs     *
		 * when a net connect more than once to the same pin class on the same    *
		 * logic block.  Only a weird architecture would allow this.              */

		if (linked_rc_ptr != nullptr) {

			/* The first time I hit a multiply-used SINK, I choose the largest delay  *
			 * from this net to this SINK and use it for every connection to this     *
			 * SINK by this net.                                                      */

			do {
				rc_node = linked_rc_ptr->rc_node;
				if (rc_node->Tdel > Tmax) {
					Tmax = rc_node->Tdel;
					rr_node_to_rc_node[inode].rc_node = rc_node;
				}
				next_ptr = linked_rc_ptr->next;
				free(linked_rc_ptr);
				linked_rc_ptr = next_ptr;
			} while (linked_rc_ptr != nullptr); /* End do while */

			rr_node_to_rc_node[inode].next = nullptr;
		}
		/* End of if multiply-used SINK */
		net_delay[net_id][ipin] = Tmax;
	}
}

static void load_one_constant_net_delay(vtr::vector<ClusterNetId, float *> &net_delay, ClusterNetId net_id, float delay_value) {

	/* Sets each entry of the net_delay array for net inet to delay_value.     */
	unsigned int ipin;
	auto& cluster_ctx = g_vpr_ctx.clustering();

	for (ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++)
		net_delay[net_id][ipin] = delay_value;
}

static void free_rc_tree(t_rc_node * rc_root,
		t_rc_node ** rc_node_free_list_ptr,
		t_linked_rc_edge ** rc_edge_free_list_ptr) {

	/* Puts the rc tree pointed to by rc_root back on the free list.  Depth-     *
	 * first post-order traversal via recursion.                                 */

	t_rc_node *rc_node, *child_node;
	t_linked_rc_edge *rc_edge, *next_edge;

	rc_node = rc_root;
	rc_edge = rc_node->u.child_list;

	while (rc_edge != nullptr) { /* For all children */
		child_node = rc_edge->child;
		free_rc_tree(child_node, rc_node_free_list_ptr, rc_edge_free_list_ptr);
		next_edge = rc_edge->next;
		free_linked_rc_edge(rc_edge, rc_edge_free_list_ptr);
		rc_edge = next_edge;
	}

	free_rc_node(rc_node, rc_node_free_list_ptr);
}

static void reset_rr_node_to_rc_node(t_linked_rc_ptr * rr_node_to_rc_node, ClusterNetId net_id) {

	/* Resets the rr_node_to_rc_node mapping entries that were set during       *
	 * construction of the RC tree for net inet.  Any extra linked list entries *
	 * added to deal with a SINK being connected to multiple times have already *
	 * been freed by load_one_net_delay.                                        */

	t_trace *tptr;
	int inode;

    auto& route_ctx = g_vpr_ctx.routing();

	tptr = route_ctx.trace[net_id].head;

	while (tptr != nullptr) {
		inode = tptr->index;
		rr_node_to_rc_node[inode].rc_node = nullptr;
		tptr = tptr->next;
	}
}

static void free_rc_node_free_list(t_rc_node * rc_node_free_list) {

	/* Really frees (i.e. calls free()) all the rc_nodes on the free list.   */

	t_rc_node *rc_node, *next_node;

	rc_node = rc_node_free_list;

	while (rc_node != nullptr) {
		next_node = rc_node->u.next;
		free(rc_node);
		rc_node = next_node;
	}
}

static void free_rc_edge_free_list(t_linked_rc_edge * rc_edge_free_list) {

	/* Really frees (i.e. calls free()) all the rc_edges on the free list.   */

	t_linked_rc_edge *rc_edge, *next_edge;

	rc_edge = rc_edge_free_list;

	while (rc_edge != nullptr) {
		next_edge = rc_edge->next;
		free(rc_edge);
		rc_edge = next_edge;
	}
}
