/*
 Jason Luu
 Date: February 11, 2013

 Print blif representation of circuit

 Limitations: [jluu] Due to ABC requiring that all blackbox inputs be named exactly the same in the netlist to be checked as in the input netlist,
 I am forced to skip all internal connectivity checking for inputs going into subckts.  If in the future, ABC no longer treats
 blackboxes as primariy I/Os, then we should revisit this and make it so that we can do formal equivalence on a more representative netlist.
 */

#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

#include "vtr_assert.h"
#include "vtr_util.h"

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

#include "globals.h"
#include "atom_netlist.h"
#include "output_blif.h"
#include "vpr_utils.h"

#define LINELENGTH 1024
#define TABLENGTH 1

/****************** Subroutines local to this module ************************/
void print_atom_block(FILE *fpout, AtomBlockId atom_blk);
void print_routing_in_clusters(FILE *fpout, ClusterBlockId clb_index);
void print_models(FILE *fpout, t_model *user_models);

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

static void print_string(const char *str_ptr, int *column, FILE * fpout) {

	/* Prints string without making any lines longer than LINELENGTH.  Column  *
	 * points to the column in which the next character will go (both used and *
	 * updated), and fpout points to the output file.                          */

	int len;

	len = strlen(str_ptr);
	if (len + 3 > LINELENGTH) {
		vpr_throw(VPR_ERROR_PACK, __FILE__, __LINE__,
				"in print_string: String %s is too long for desired maximum line length.\n", str_ptr);
	}

	if (*column + len + 2 > LINELENGTH) {
		fprintf(fpout, "\\ \n");
		*column = TABLENGTH;
	}

	fprintf(fpout, "%s ", str_ptr);
	*column += len + 1;
}

static void print_net_name(AtomNetId net_id, int *column, FILE * fpout) {

	/* This routine prints out the atom_ctx.nlist net name (or open) and limits the    *
	 * length of a line to LINELENGTH characters by using \ to continue *
	 * lines.  net_id is the id of the atom_ctx.nlist net to be printed, while     *
	 * column points to the current printing column (column is both     *
	 * used and updated by this routine).  fpout is the output file     *
	 * pointer.                                                         */

	char *str_ptr;

	if (!net_id) {
		str_ptr = new char [6];
		sprintf(str_ptr, "open");
	} else {
        auto& atom_ctx = g_vpr_ctx.atom();
		str_ptr = new char[strlen(atom_ctx.nlist.net_name(net_id).c_str()) + 7];
		sprintf(str_ptr, "__|e%s", atom_ctx.nlist.net_name(net_id).c_str());
	}

	print_string(str_ptr, column, fpout);
	delete [] str_ptr;
}

/* Print netlist atom in blif format */
void print_atom_block(FILE *fpout, AtomBlockId atom_blk) {
	t_pb_route * pb_route;
	const t_pb_graph_node *pb_graph_node;
	t_pb_type *pb_type;

    auto& atom_ctx = g_vpr_ctx.atom();
	auto& cluster_ctx = g_vpr_ctx.clustering();

	ClusterBlockId clb_index = atom_ctx.lookup.atom_clb(atom_blk);
	VTR_ASSERT(clb_index != ClusterBlockId::INVALID());

	pb_route = cluster_ctx.clb_nlist.block_pb(clb_index)->pb_route;
	VTR_ASSERT(pb_route != nullptr);
	pb_graph_node = atom_ctx.lookup.atom_pb_graph_node(atom_blk);
	pb_type = pb_graph_node->pb_type;


    if (atom_ctx.nlist.block_type(atom_blk) == AtomBlockType::INPAD) {
		int node_index = pb_graph_node->output_pins[0][0].pin_count_in_cluster;
		fprintf(fpout, ".names %s clb_%zu_rr_node_%d\n", atom_ctx.nlist.block_name(atom_blk).c_str(), size_t(clb_index), node_index);
		fprintf(fpout, "1 1\n\n");
    } else if (atom_ctx.nlist.block_type(atom_blk) == AtomBlockType::OUTPAD) {
		int node_index = pb_graph_node->input_pins[0][0].pin_count_in_cluster;

        //Don't add a buffer if the name is prefixed with :out, just remove the :out
        auto input_pins = atom_ctx.nlist.block_input_pins(atom_blk);
        VTR_ASSERT(input_pins.size() == 1);
        auto input_pin = *input_pins.begin();
        auto input_net = atom_ctx.nlist.pin_net(input_pin);

        const char* outpad_input_net = atom_ctx.nlist.net_name(input_net).c_str();
        const char* trimmed_outpad_name = atom_ctx.nlist.block_name(atom_blk).c_str() + 4;
		if (strcmp(outpad_input_net, trimmed_outpad_name) != 0) {
			fprintf(fpout, ".names %s clb_%zu_rr_node_%d\n", trimmed_outpad_name, size_t(clb_index), node_index);
			fprintf(fpout, "1 1\n\n");
		}
	}
	else if(strcmp(atom_ctx.nlist.block_model(atom_blk)->name, MODEL_NAMES) == 0) {
		/* Print a LUT, a LUT has K input pins and one output pin */
		fprintf(fpout, ".names ");

        VTR_ASSERT(pb_type->num_ports == 2);

        //Print the input port
		for (int i = 0; i < pb_type->num_ports; i++) {
			if (pb_type->ports[i].type == IN_PORT) {
				/* LUTs receive special handling because a LUT has logically equivalent inputs.
					The intra-logic block router may have taken advantage of logical equivalence so we need to unscramble the inputs when we output the LUT logic.
				*/
				VTR_ASSERT(pb_type->ports[i].is_clock == false);

                AtomPortId port_id = atom_ctx.nlist.find_port(atom_blk, pb_type->ports[i].name);
                if(port_id) {
                    for (int j = 0; j < pb_type->ports[i].num_pins; j++) {
                        AtomPinId pin_id = atom_ctx.nlist.port_pin(port_id, j);
                        if(pin_id) {
                            AtomNetId net_id = atom_ctx.nlist.pin_net(pin_id);
                            VTR_ASSERT(net_id);

                            int k;
                            for (k = 0; k < pb_type->ports[i].num_pins; k++) {
                                int node_index = pb_graph_node->input_pins[0][k].pin_count_in_cluster;
                                AtomNetId a_net_id = pb_route[node_index].atom_net_id;
                                if(a_net_id) {
                                    if(a_net_id == net_id) {
                                        fprintf(fpout, "clb_%zu_rr_node_%d ", size_t(clb_index), pb_route[node_index].driver_pb_pin_id);
                                        break;
                                    }
                                }
                            }
                            if(k == pb_type->ports[i].num_pins) {
                                /* Failed to find LUT input, a netlist error has occurred */
                                vpr_throw(VPR_ERROR_PACK, __FILE__, __LINE__,
                                    "LUT %s missing input %s post packing please file a bug report\n",
                                    atom_ctx.nlist.block_name(atom_blk).c_str(), atom_ctx.nlist.net_name(net_id).c_str());
                            }
                        }
                    }
                }
			}
		}

        //Print the output port
		for (int i = 0; i < pb_type->num_ports; i++) {
			if (pb_type->ports[i].type == OUT_PORT) {
				int node_index = pb_graph_node->output_pins[0][0].pin_count_in_cluster;
				VTR_ASSERT(pb_type->ports[i].num_pins == 1);

                auto port_id = atom_ctx.nlist.find_port(atom_blk, pb_type->ports[i].name);
                auto pin_id = atom_ctx.nlist.port_pin(port_id, 0);
                VTR_ASSERT(pin_id);
                VTR_ASSERT(atom_ctx.nlist.pin_net(pin_id) == pb_route[node_index].atom_net_id);

				fprintf(fpout, "%s\n", atom_ctx.nlist.block_name(atom_blk).c_str());
			}
		}

        //Print the truth table
        const auto& truth_table = atom_ctx.nlist.block_truth_table(atom_blk);
        for(auto row_iter = truth_table.rbegin(); row_iter != truth_table.rend(); ++row_iter) {
            const auto& row = *row_iter;
            for(auto iter = row.begin(); iter != row.end(); ++iter) {
                if(iter == --row.end()) {
                    fprintf(fpout, " ");
                }
                switch(*iter) {
                    case vtr::LogicValue::TRUE: fprintf(fpout, "1"); break;
                    case vtr::LogicValue::FALSE: fprintf(fpout, "0"); break;
                    case vtr::LogicValue::DONT_CARE: fprintf(fpout, "-"); break;
                    default: VTR_ASSERT(false);
                }
                if(iter == --row.end()) {
                    VTR_ASSERT(*iter != vtr::LogicValue::DONT_CARE);
                }
            }
            fprintf(fpout, "\n");
        }

        //Print the intermediate buffers for the output
		for (int i = 0; i < pb_type->num_ports; i++) {
			if (pb_type->ports[i].type == OUT_PORT) {
				int node_index = pb_graph_node->output_pins[0][0].pin_count_in_cluster;
				VTR_ASSERT(pb_type->ports[i].num_pins == 1);

                auto port_id = atom_ctx.nlist.find_port(atom_blk, pb_type->ports[i].name);
                auto pin_id = atom_ctx.nlist.port_pin(port_id, 0);
                VTR_ASSERT(pin_id);
                VTR_ASSERT(atom_ctx.nlist.pin_net(pin_id) == pb_route[node_index].atom_net_id);

				fprintf(fpout, "\n.names %s clb_%zu_rr_node_%d\n", atom_ctx.nlist.block_name(atom_blk).c_str(), size_t(clb_index), node_index);
				fprintf(fpout, "1 1\n");
			}
		}
	} else if (strcmp(atom_ctx.nlist.block_model(atom_blk)->name, MODEL_LATCH) == 0) {
		/* Print a flip-flop.  A flip-flop has a D input, a Q output, and a clock input */
		fprintf(fpout, ".latch ");
		VTR_ASSERT(pb_type->num_ports == 3);
		for (int i = 0; i < pb_type->num_ports; i++) {
			if (pb_type->ports[i].type == IN_PORT
					&& pb_type->ports[i].is_clock == false) {
				VTR_ASSERT(pb_type->ports[i].num_pins == 1);

                auto input_pins = atom_ctx.nlist.block_input_pins(atom_blk);
                VTR_ASSERT(input_pins.size() == 1);
                VTR_ASSERT_MSG(atom_ctx.nlist.pin_net(*input_pins.begin()), "Valid input net");

				int node_index = pb_graph_node->input_pins[0][0].pin_count_in_cluster;
				fprintf(fpout, "clb_%zu_rr_node_%d ", size_t(clb_index),	pb_route[node_index].driver_pb_pin_id);
			} else if (pb_type->ports[i].type == OUT_PORT) {
				VTR_ASSERT(pb_type->ports[i].num_pins == 1);

                auto output_pins = atom_ctx.nlist.block_output_pins(atom_blk);
                VTR_ASSERT(output_pins.size() == 1);
                auto output_net_id = atom_ctx.nlist.pin_net(*output_pins.begin());
                VTR_ASSERT_MSG(output_net_id, "Valid output net");


				fprintf(fpout, "%s re ", atom_ctx.nlist.net_name(output_net_id).c_str());
			} else if (pb_type->ports[i].type == IN_PORT
					&& pb_type->ports[i].is_clock == true) {
				VTR_ASSERT(pb_type->ports[i].num_pins == 1);

                auto clock_pins = atom_ctx.nlist.block_clock_pins(atom_blk);
                VTR_ASSERT(clock_pins.size() == 1);
                VTR_ASSERT_MSG(atom_ctx.nlist.pin_net(*clock_pins.begin()), "Valid clock net");

				int node_index = pb_graph_node->clock_pins[0][0].pin_count_in_cluster;
				fprintf(fpout, "clb_%zu_rr_node_%d 2", size_t(clb_index), pb_route[node_index].driver_pb_pin_id);
			} else {
				VTR_ASSERT(0);
			}
		}
		fprintf(fpout, "\n");
		for (int i = 0; i < pb_type->num_ports; i++) {
			if (pb_type->ports[i].type == OUT_PORT) {
				int node_index = pb_graph_node->output_pins[0][0].pin_count_in_cluster;
				VTR_ASSERT(pb_type->ports[i].num_pins == 1);
                AtomPortId port_id = atom_ctx.nlist.find_port(atom_blk, pb_type->ports[i].name);
                auto net_id = atom_ctx.nlist.port_net(port_id, 0);
				VTR_ASSERT(net_id == pb_route[node_index].atom_net_id);
				fprintf(fpout, "\n.names %s clb_%zu_rr_node_%d\n", atom_ctx.nlist.net_name(net_id).c_str(), size_t(clb_index), node_index);
				fprintf(fpout, "1 1\n");
			}
		}
	} else {
		const t_model *cur = atom_ctx.nlist.block_model(atom_blk);
		fprintf(fpout, ".subckt %s \\\n", cur->name);

		/* Print input ports */
		t_model_ports *port = cur->inputs;

		while (port != nullptr) {
            AtomPortId port_id = atom_ctx.nlist.find_port(atom_blk, port->name);
			for (int i = 0; i < port->size; i++) {
                fprintf(fpout, "%s[%d]=", port->name, i);

				if (port->is_clock == true) {
					VTR_ASSERT(port->index == 0);
					VTR_ASSERT(port->size == 1);

                    VTR_ASSERT(atom_ctx.nlist.port_type(port_id) == PortType::CLOCK);
                }

                AtomNetId net_id = atom_ctx.nlist.port_net(port_id, i);

                //Output the net
                if(net_id) {
                    fprintf(fpout, "%s", atom_ctx.nlist.net_name(net_id).c_str());
                } else {
                    fprintf(fpout, "unconn");
                }

                fprintf(fpout, " "); //Space after port assignment
				if (i % 4 == 3) {
					if (i + 1 < port->size) {
						fprintf(fpout, "\\\n");
					}
				}
			}
			port = port->next;
			fprintf(fpout, "\\\n");
		}

		/* Print output ports */
		port = cur->outputs;
		while (port != nullptr) {
            AtomPortId port_id = atom_ctx.nlist.find_port(atom_blk, port->name);
			for (int i = 0; i < port->size; i++) {
                AtomNetId net_id = atom_ctx.nlist.port_net(port_id, i);

                if(net_id) {
                    fprintf(fpout, "%s[%d]=%s ", port->name, i, atom_ctx.nlist.net_name(net_id).c_str());
                } else {
                    fprintf(fpout, "%s[%d]=unconn ", port->name, i);
                }

				if (i % 4 == 3) {
					if (i + 1 < port->size) {
						fprintf(fpout, "\\\n");
					}
				}
			}
			port = port->next;
			if (port != nullptr) {
				fprintf(fpout, "\\\n");
			}
		}
		fprintf(fpout, "\n");
		fprintf(fpout, "\n");


        /* Print output buffers */
        port = cur->outputs;
        while (port != nullptr) {
            AtomPortId port_id = atom_ctx.nlist.find_port(atom_blk, port->name);
            for (int ipin = 0; ipin < port->size; ipin++) {
                AtomNetId net_id = atom_ctx.nlist.port_net(port_id, ipin);
                if (net_id) {
                    t_pb_graph_pin *pb_graph_pin = get_pb_graph_node_pin_from_model_port_pin(port, ipin, pb_graph_node);
                    fprintf(fpout, ".names %s clb_%zu_rr_node_%d\n", atom_ctx.nlist.net_name(net_id).c_str(), size_t(clb_index), pb_graph_pin->pin_count_in_cluster);
                    fprintf(fpout, "1 1\n\n");
                }
            }
            port = port->next;
        }
	}
}

void print_routing_in_clusters(FILE *fpout, ClusterBlockId clb_index) {
	t_pb_route * pb_route;
	t_pb_graph_node *pb_graph_node;
	t_pb_graph_node *pb_graph_node_of_pin;
	int max_pb_graph_pin;
	t_pb_graph_pin** pb_graph_pin_lookup;

	auto& cluster_ctx = g_vpr_ctx.clustering();

	/* print routing of clusters */
	pb_graph_pin_lookup = alloc_and_load_pb_graph_pin_lookup_from_index(cluster_ctx.clb_nlist.block_type(clb_index));
	pb_graph_node = cluster_ctx.clb_nlist.block_pb(clb_index)->pb_graph_node;
	max_pb_graph_pin = pb_graph_node->total_pb_pins;
	pb_route = cluster_ctx.clb_nlist.block_pb(clb_index)->pb_route;

	for(int i = 0; i < max_pb_graph_pin; i++) {
		if(pb_route[i].atom_net_id) {
			int column = 0;
			pb_graph_node_of_pin = pb_graph_pin_lookup[i]->parent_node;

			/* Print interconnect */
			if(pb_graph_node_of_pin->pb_type->num_modes != 0 && pb_route[i].driver_pb_pin_id == OPEN) {
				/* Logic block input pin */
				VTR_ASSERT(pb_graph_node_of_pin->parent_pb_graph_node == nullptr);
				fprintf(fpout, ".names ");
				print_net_name(pb_route[i].atom_net_id, &column, fpout);
				fprintf(fpout, " clb_%zu_rr_node_%d\n", size_t(clb_index), i);
				fprintf(fpout, "1 1\n\n");
			} else if (pb_graph_node_of_pin->pb_type->num_modes != 0 && pb_graph_node_of_pin->parent_pb_graph_node == nullptr) {
				/* Logic block output pin */
				fprintf(fpout, ".names clb_%zu_rr_node_%d ", size_t(clb_index), pb_route[i].driver_pb_pin_id);
				print_net_name(pb_route[i].atom_net_id, &column, fpout);
				fprintf(fpout, "\n");
				fprintf(fpout, "1 1\n\n");
			} else if (pb_graph_node_of_pin->pb_type->num_modes != 0 || pb_graph_pin_lookup[i]->port->type != OUT_PORT) {
				/* Logic block internal pin */
				fprintf(fpout, ".names clb_%zu_rr_node_%d clb_%zu_rr_node_%d\n", size_t(clb_index), pb_route[i].driver_pb_pin_id, size_t(clb_index), i);
				fprintf(fpout, "1 1\n\n");
			}
		}
	}

	free_pb_graph_pin_lookup_from_index(pb_graph_pin_lookup);
}

/* Print list of models to file */
void print_models(FILE *fpout, t_model *user_models) {

	t_model *cur;
	cur = user_models;

	while (cur != nullptr) {
		fprintf(fpout, "\n");
		fprintf(fpout, ".model %s\n", cur->name);

		/* Print input ports */
		t_model_ports *port = cur->inputs;
		if (port == nullptr) {
			fprintf(fpout, ".inputs \n");
		}
		else {
			fprintf(fpout, ".inputs \\\n");
		}
		while (port != nullptr) {
			for (int i = 0; i < port->size; i++) {
				fprintf(fpout, "%s[%d] ", port->name, i);
				if (i % 8 == 4) {
					if (i + 1 < port->size) {
						fprintf(fpout, "\\\n");
					}
				}
			}
			port = port->next;
			if (port != nullptr) {
				fprintf(fpout, "\\\n");
			}
			else {
				fprintf(fpout, "\n");
			}
		}
		/* Print input ports */
		port = cur->outputs;
		if (port == nullptr) {
			fprintf(fpout, ".outputs \n");
		}
		else {
			fprintf(fpout, ".outputs \\\n");
		}
		while (port != nullptr) {
			for (int i = 0; i < port->size; i++) {
				fprintf(fpout, "%s[%d] ", port->name, i);
				if (i % 8 == 4) {
					if (i + 1 < port->size) {
						fprintf(fpout, "\\\n");
					}
				}
			}
			port = port->next;
			if (port != nullptr) {
				fprintf(fpout, "\\\n");
			}
			else {
				fprintf(fpout, "\n");
			}
		}
		fprintf(fpout, ".blackbox\n");
		fprintf(fpout, ".end\n");
		cur = cur->next;
	}
}

/* This routine dumps out the output netlist in a format suitable for   *
* input to vpr.  This routine also dumps out the internal structure of  *
* the cluster, in essentially a graph based format.                     */
void output_blif(const t_arch *arch, const char *out_fname) {
	FILE *fpout;
	int column;

	auto& cluster_ctx = g_vpr_ctx.clustering();

	// Check that there's at least one block that exists
	if(cluster_ctx.clb_nlist.block_pb(ClusterBlockId(0))->pb_route == nullptr) {
		return;
	}

    auto& atom_ctx = g_vpr_ctx.atom();

	fpout = vtr::fopen(out_fname, "w");

	column = 0;
	fprintf(fpout, ".model %s\n", atom_ctx.nlist.netlist_name().c_str());

	/* Print out all input and output pads. */
	fprintf(fpout, "\n.inputs ");
	for (auto blk_id : atom_ctx.nlist.blocks()) {
		if (atom_ctx.nlist.block_type(blk_id) == AtomBlockType::INPAD) {
			print_string(atom_ctx.nlist.block_name(blk_id).c_str(), &column, fpout);
		}
	}

	column = 0;
	fprintf(fpout, "\n.outputs ");
	for (auto blk_id : atom_ctx.nlist.blocks()) {
		if (atom_ctx.nlist.block_type(blk_id) == AtomBlockType::OUTPAD) {
			/* remove output prefix "out:" */
			print_string(atom_ctx.nlist.block_name(blk_id).c_str() + 4, &column, fpout);
		}
	}

	column = 0;

	fprintf(fpout, "\n\n");
	fprintf(fpout, ".names unconn\n");
	fprintf(fpout, " 0\n\n");

	/* print out all circuit elements */
	for (auto blk_id : atom_ctx.nlist.blocks()) {
		print_atom_block(fpout, blk_id);
	}

	for(auto clb_index : cluster_ctx.clb_nlist.blocks()) {
		print_routing_in_clusters(fpout, clb_index);
	}

	fprintf(fpout, "\n.end\n");

	print_models(fpout, arch->models);

	fclose(fpout);
}
