/*
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "odin_types.h"
#include "odin_globals.h"

#include "netlist_utils.h"
#include "odin_util.h"
#include "output_blif.h"

#include "node_creation_library.h"

#include "multipliers.h"
#include "hard_blocks.h"
#include "adders.h"
#include "subtractions.h"
#include "vtr_util.h"
#include "vtr_memory.h"

bool haveOutputLatchBlackbox = false;

void depth_first_traversal_to_output(short marker_value, FILE *fp, netlist_t *netlist);
void depth_traverse_output_blif(nnode_t *node, int traverse_mark_number, FILE *fp);
void output_node(nnode_t *node, short traverse_number, FILE *fp);
void define_logical_function(nnode_t *node, FILE *out);
void define_set_input_logical_function(nnode_t *node, const char *bit_output, FILE *out);
void define_ff(nnode_t *node, FILE *out);
void define_decoded_mux(nnode_t *node, FILE *out);
void output_blif_pin_connect(nnode_t *node, FILE *out);


static void print_input_pin(FILE *out, nnode_t *node, long pin_idx)
{
	oassert(pin_idx < node->num_input_pins);
	nnet_t *net = node->input_pins[pin_idx]->net;
	if (!net->driver_pin || !net->driver_pin->node)
	{
		// Add a warning for an undriven net.
		int line_number = node->related_ast_node?node->related_ast_node->line_number:0;
		warning_message(NETLIST_ERROR, line_number, -1, 
			"Net %s driving node %s is itself undriven.", 
			net->name, node->name);

		fprintf(out, " %s", "unconn");
	}
	else if (global_args.high_level_block.provenance() == argparse::Provenance::SPECIFIED
	&& net->driver_pin->node->related_ast_node != NULL)
	{
		fprintf(out, " %s^^%i-%i", 
		net->driver_pin->node->name,
		net->driver_pin->node->related_ast_node->far_tag, 
		net->driver_pin->node->related_ast_node->high_number);
	}
	else
	{
		if (net->driver_pin->name != NULL &&
				((net->driver_pin->node->type == MULTIPLY) ||
				(net->driver_pin->node->type == HARD_IP) ||
				(net->driver_pin->node->type == MEMORY) ||
				(net->driver_pin->node->type == ADD) ||
				(net->driver_pin->node->type == MINUS)))
		{
			fprintf(out, " %s", net->driver_pin->name);
		}
		else
		{
			fprintf(out, " %s", net->driver_pin->node->name);
		}
	}
	
}

static void print_output_pin(FILE *out, nnode_t *node)
{
	/* now print the output */
	if (node->related_ast_node != NULL
	&& global_args.high_level_block.provenance() == argparse::Provenance::SPECIFIED)
		fprintf(out, " %s^^%i-%i", 
			node->name, 
			node->related_ast_node->far_tag, 
			node->related_ast_node->high_number);
	else
		fprintf(out, " %s", node->name);
}

static void print_input_pin_list(FILE *out, nnode_t *node)
{
	for( long i = 0; i < node->num_input_pins; i++)
	{
		print_input_pin(out, node, i);
	}
}

static void print_dot_names_header(FILE *out, nnode_t *node)
{
	fprintf(out, ".names");
	print_input_pin_list(out, node);	
	
	oassert(node->num_output_pins == 1);
	print_output_pin(out, node);
	fprintf(out, "\n");

}


/*---------------------------------------------------------------------------
 * (function: output_blif)
 * 	The function that prints out the details for a blif formatted file
 *-------------------------------------------------------------------------*/
void output_blif(const char *file_name, netlist_t *netlist)
{
	FILE *out;

	/* open the file for output */
	if (global_args.high_level_block.provenance() == argparse::Provenance::SPECIFIED )
	{
		std::string out_file = "";
		out_file = out_file + file_name + "_" + global_args.high_level_block.value() + ".blif";
		out = fopen(out_file.c_str(), "w+");
	}
	else
	{
		out = fopen(file_name, "w+");
	}

	if (out == NULL)
	{
		error_message(NETLIST_ERROR, -1, -1, "Could not open output file %s\n", file_name);
	}

	fprintf(out, ".model %s\n", top_module->children[0]->types.identifier);


	/* generate all the signals */

	fprintf(out, ".inputs");
	for (long i = 0; i < netlist->num_top_input_nodes; i++)
	{
		nnode_t *top_input_node = netlist->top_input_nodes[i];
		print_output_pin(out, top_input_node);
	}
	fprintf(out, "\n");


	fprintf(out, ".outputs");
	for (long i = 0; i < netlist->num_top_output_nodes; i++)
	{
		nnode_t *top_output_node = netlist->top_output_nodes[i];
		if (top_output_node->input_pins[0]->net->driver_pin == NULL)
		{
			warning_message(NETLIST_ERROR, 
				top_output_node->related_ast_node->line_number, 
				top_output_node->related_ast_node->file_number, 
				"This output is undriven (%s) and will be removed\n", 
				top_output_node->name);
		}
		else
		{
			
			print_output_pin(out, top_output_node);
		}
	}
	fprintf(out, "\n");

	/* add gnd, unconn, and vcc */
	fprintf(out, "\n.names gnd\n.names unconn\n.names vcc\n1\n");
	fprintf(out, "\n");

	/* traverse the internals of the flat net-list */
	if (strcmp(configuration.output_type.c_str(), "blif") == 0)
	{
		depth_first_traversal_to_output(OUTPUT_TRAVERSE_VALUE, out, netlist);
	}
	else
	{
		error_message(NETLIST_ERROR, 0, -1, "%s", "Invalid output file type.");
	}

	/* connect all the outputs up to the last gate */
	for (long i = 0; i < netlist->num_top_output_nodes; i++)
	{
		nnode_t *node = netlist->top_output_nodes[i];
		
		fprintf(out, ".names");
		print_input_pin(out,node,0);
		print_output_pin(out, node);
		fprintf(out, "\n");

		fprintf(out, "1 1\n\n");
	}

	/* finish off the top level module */
	fprintf(out, ".end\n");
	fprintf(out, "\n");

	/* Print out any hard block modules */
	add_the_blackbox_for_mults(out);
	add_the_blackbox_for_adds(out);

	output_hard_blocks(out);
	fclose(out);
}

/*---------------------------------------------------------------------------
 * (function: depth_first_traversal_to_parital_map()
 *-------------------------------------------------------------------------------------------*/
void depth_first_traversal_to_output(short marker_value, FILE *fp, netlist_t *netlist)
{
	int i;

	netlist->gnd_node->name = vtr::strdup("gnd");
	netlist->vcc_node->name = vtr::strdup("vcc");
	netlist->pad_node->name = vtr::strdup("unconn");
	/* now traverse the ground, vcc, and unconn pins */
	depth_traverse_output_blif(netlist->gnd_node, marker_value, fp);
	depth_traverse_output_blif(netlist->vcc_node, marker_value, fp);
	depth_traverse_output_blif(netlist->pad_node, marker_value, fp);

	/* start with the primary input list */
	for (i = 0; i < netlist->num_top_input_nodes; i++)
	{
		if (netlist->top_input_nodes[i] != NULL)
		{
			depth_traverse_output_blif(netlist->top_input_nodes[i], marker_value, fp);
		}
	}
}

/*--------------------------------------------------------------------------
 * (function: depth_first_traverse)
 *------------------------------------------------------------------------*/
void depth_traverse_output_blif(nnode_t *node, int traverse_mark_number, FILE *fp)
{
	int i, j;
	nnode_t *next_node;
	nnet_t *next_net;

	if (node->traverse_visited == traverse_mark_number)
	{
		return;
	}
	else
	{
		/* ELSE - this is a new node so depth visit it */

		/* POST traverse  map the node since you might delete */
		output_node(node, traverse_mark_number, fp);

		/* mark that we have visitied this node now */
		node->traverse_visited = traverse_mark_number;

		for (i = 0; i < node->num_output_pins; i++)
		{
			if (node->output_pins[i]->net == NULL)
				continue;

			next_net = node->output_pins[i]->net;
			for (j = 0; j < next_net->num_fanout_pins; j++)
			{
				if (next_net->fanout_pins[j] == NULL)
					continue;

				next_node = next_net->fanout_pins[j]->node;
				if (next_node == NULL)
					continue;

				/* recursive call point */
				depth_traverse_output_blif(next_node, traverse_mark_number, fp);
			}
		}

	}
}
/*-------------------------------------------------------------------
 * (function: output_node)
 * 	Depending on node type, figures out what to print for this node
 *------------------------------------------------------------------*/
void output_node(nnode_t *node, short /*traverse_number*/, FILE *fp)
{
	switch (node->type)
	{
		case GT:
			define_set_input_logical_function(node, "100 1\n", fp);
			oassert(node->num_input_pins == 3);
			oassert(node->input_pins[2] != NULL);
			break;
		case LT:
			define_set_input_logical_function(node, "010 1\n", fp); // last input decides if this
			oassert(node->num_input_pins == 3);
			oassert(node->input_pins[2] != NULL);
			break;
		case ADDER_FUNC:
			define_set_input_logical_function(node, "001 1\n010 1\n100 1\n111 1\n", fp);
			break;
		case CARRY_FUNC:
			define_set_input_logical_function(node, "011 1\n101 1\n110 1\n111 1\n", fp);
			break;
		case BITWISE_NOT:
			define_set_input_logical_function(node, "0 1\n", fp);
			break;

		case LOGICAL_AND:
		case LOGICAL_OR:
		case LOGICAL_XOR:
		case LOGICAL_XNOR:
		case LOGICAL_NAND:
		case LOGICAL_NOR:
		case LOGICAL_EQUAL:
		case NOT_EQUAL:
		case LOGICAL_NOT:
			define_logical_function(node, fp);
			break;

		case MUX_2:
			define_decoded_mux(node, fp);
			break;

		case FF_NODE:
			define_ff(node, fp);
			break;

		case MULTIPLY:
			oassert(hard_multipliers); /* should be soft logic! */
			define_mult_function(node, fp);
			break;

		//case FULLADDER:
		case ADD:
			oassert(hard_adders); /* should be soft logic! */
			define_add_function(node, fp);
			break;

		case MINUS:
			oassert(hard_adders); /* should be soft logic! */
			define_add_function(node, fp);
			break;

		case MEMORY:
		case HARD_IP:
			define_hard_block(node, fp);
			break;
		case INPUT_NODE:
		case OUTPUT_NODE:
		case PAD_NODE:
		case CLOCK_NODE:
		case GND_NODE:
		case VCC_NODE:
			/* some nodes already converted */
			break;

		case BITWISE_AND:
		case BITWISE_NAND:
		case BITWISE_NOR:
		case BITWISE_XNOR:
		case BITWISE_XOR:
		case BITWISE_OR:
		case BUF_NODE:
		case MULTI_PORT_MUX:
		case SL:
		case SR:
        case ASR:
		case CASE_EQUAL:
		case CASE_NOT_EQUAL:
		case DIVIDE:
		case MODULO:
		case GTE:
		case LTE:
		default:
			/* these nodes should have been converted to softer versions */
			error_message(NETLIST_ERROR, 0,-1, "%s", "Output blif: node should have been converted to softer version.");
			break;
	}
}

/*-------------------------------------------------------------------------
 * (function: define_logical_function)
 *-----------------------------------------------------------------------*/
void define_logical_function(nnode_t *node, FILE *out)
{
	int i, j;
	char *temp_string;

	print_dot_names_header(out, node);

	/* print out the blif definition of this gate */
	switch (node->type)
	{
		case LOGICAL_AND:
		{
			/* generates: 111111 1 */
			for (i = 0; i < node->num_input_pins; i++)
			{
				fprintf(out, "1");
			}
			fprintf(out, " 1\n");
			break;
		}
		case LOGICAL_OR:
		{
			/* generates: 1----- 1\n-1----- 1\n ... */
			for (i = 0; i < node->num_input_pins; i++)
			{
				for (j = 0; j < node->num_input_pins; j++)
				{
					if (i == j)
						fprintf(out, "1");
					else
						fprintf(out, "-");
				}
				fprintf(out, " 1\n");
			}
			break;
		}
		case LOGICAL_NAND:
		{
			/* generates: 0----- 1\n-0----- 1\n ... */
			for (i = 0; i < node->num_input_pins; i++)
			{
				for (j = 0; j < node->num_input_pins; j++)
				{
					if (i == j)
						fprintf(out, "0");
					else
						fprintf(out, "-");
				}
				fprintf(out, " 1\n");
			}
			break;
		}
		case LOGICAL_NOT:
		case LOGICAL_NOR:
		{
			/* generates: 0000000 1 */
			for (i = 0; i < node->num_input_pins; i++)
			{
				fprintf(out, "0");
			}
			fprintf(out, " 1\n");
			break;
		}
		case LOGICAL_EQUAL:
		case LOGICAL_XOR:
		{
			oassert(node->num_input_pins <= 3);
			/* generates: a 1 when odd number of 1s */
			for (i = 0; i < my_power(2, node->num_input_pins); i++)
			{
				if ((i % 8 == 1) || (i % 8 == 2) || (i % 8 == 4) || (i % 8 == 7))
				{
					temp_string = convert_long_to_bit_string(i, node->num_input_pins);
					fprintf(out, "%s", temp_string);
					vtr::free(temp_string);
					fprintf(out, " 1\n");
				}
			}
			break;
		}
		case NOT_EQUAL:
		case LOGICAL_XNOR:
		{
			oassert(node->num_input_pins <= 3);
			for (i = 0; i < my_power(2, node->num_input_pins); i++)
			{
				if ((i % 8 == 0) || (i % 8 == 3) || (i % 8 == 5) || (i % 8 == 6))
				{
					temp_string = convert_long_to_bit_string(i, node->num_input_pins);
					fprintf(out, "%s", temp_string);
					vtr::free(temp_string);
					fprintf(out, " 1\n");
				}
			}
			break;
		}
		default:
			oassert(false);
			break;
	}

	fprintf(out, "\n");
}

/*------------------------------------------------------------------------
 * (function: define_set_input_logical_function)
 *----------------------------------------------------------------------*/
void define_set_input_logical_function(nnode_t *node, const char *bit_output, FILE *out)
{

	oassert(node->num_input_pins >= 1);

	print_dot_names_header(out, node);

	/* print out the blif definition of this gate */
	if (bit_output != NULL)
	{
		fprintf(out, "%s", bit_output);
	}
	fprintf(out, "\n");
}


/*-------------------------------------------------------------------------
 * (function: define_ff)
 *-----------------------------------------------------------------------*/
void define_ff(nnode_t *node, FILE *out)
{
	oassert(node->num_output_pins == 1);
	oassert(node->num_input_pins == 2);


	int initial_value = global_args.sim_initial_value;
	if(node->has_initial_value)
		initial_value = node->initial_value;
	
	/* By default, latches value are unknown, represented by 3 in a BLIF file
	and by -1 internally in ODIN */
	// TODO switch to default!! to avoid confusion
	if(initial_value == -1)
		initial_value = 3;

	// grab the edge sensitivity of the flip flop
	const char *edge_type_str = edge_type_blif_str(node); 

	std::string input;
	std::string output;
	std::string clock_driver;

	fprintf(out, ".latch");

	/* input */
	print_input_pin(out,node, 0);

	/* output */
	print_output_pin(out,node);

	/* sensitivity */
	fprintf(out, " %s", edge_type_str);
	
	/* clock */
	print_input_pin(out,node, 1);

	/* initial value */
	fprintf(out, " %d\n\n", initial_value);
}

/*--------------------------------------------------------------------------
 * (function: define_decoded_mux)
 *------------------------------------------------------------------------*/
void define_decoded_mux(nnode_t *node, FILE *out)
{
	oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);
	print_dot_names_header(out, node);


	/* generates: 1----- 1\n-1----- 1\n ... */
	for (long i = 0; i < node->input_port_sizes[0]; i++)
	{
		for (long j = 0; j < node->num_input_pins; j++)
		{
			if (i == j)
				fprintf(out, "1");
			else if (i+node->input_port_sizes[0] == j)
				fprintf(out, "1");
			else if (i > node->input_port_sizes[0])
				fprintf(out, "0");
			else
				fprintf(out, "-");
		}
		fprintf(out, " 1\n");
	}

	fprintf(out, "\n");
}
