#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "verilog_preprocessor.h"
#include "odin_types.h"
#include "vtr_util.h"
#include "vtr_memory.h"
#include "odin_util.h"
#include <stdbool.h>
#include <regex>
#include <string>

#include "odin_buffer.hpp"

#define DefaultSize 20

/* Structs */
struct veri_include
{
	char *path;
	struct veri_include *included_from;
	int	line;
};

struct veri_define
{
	char *symbol;
	char *value;
	int line;
	veri_include *defined_in;
};

struct veri_Includes
{
	veri_include **included_files;
	int current_size;
	int current_index;
};

struct veri_Defines
{
	veri_define **defined_constants;
	int current_size;
	int current_index;
};

/* Stack for tracking conditional branches --------------------------------- */
struct veri_flag_node
{
	int flag;
	struct veri_flag_node *next;
};

struct veri_flag_stack
{
	veri_flag_node *top;
} ;

void clean_veri_define(veri_define *current);
void clean_veri_include(veri_include *current);

/* Adding/Removing includes or defines */
int add_veri_define(char *symbol, char *value, int line, veri_include *included_from);
char* ret_veri_definedval(const char *symbol);
int veri_is_defined(const char * symbol);
veri_include* add_veri_include(const char *path, int line, veri_include *included_from);

/* Preprocessor ------------------------------------------------------------- */
void veri_preproc_bootstraped(FILE *source, FILE *preproc_producer, veri_include *current_include);

/* stack methods */
int top(veri_flag_stack *stack);
int pop(veri_flag_stack *stack);
void push(veri_flag_stack *stack, int flag);

/* General Utility methods ------------------------------------------------- */
static char* get_line(FILE *source, bool *eof, bool *multiline_comment, const char *one_line_comment, const char *n_line_comment_ST, const char *n_line_comment_END);


/* Globals */
struct veri_Includes veri_includes;
struct veri_Defines veri_defines;

const char symbol_char[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789";


/*
 * Initialize the preprocessor by allocating sufficient memory and setting sane values
 */
int init_veri_preproc()
{
	veri_includes.included_files = (veri_include **) vtr::calloc(DefaultSize, sizeof(veri_include *));
	if (veri_includes.included_files == NULL)
	{
		perror("veri_includes.included_files : vtr::calloc ");
		return -1;
	}
	veri_includes.current_size = DefaultSize;
	veri_includes.current_index = 0;

	veri_defines.defined_constants = (veri_define **) vtr::calloc(DefaultSize, sizeof(veri_define *));
	if (veri_defines.defined_constants == NULL)
	{
		perror("veri_defines.defined_constants : vtr::calloc ");
		return -1;
	}
	veri_defines.current_size = DefaultSize;
	veri_defines.current_index = 0;
	return 0;
}

/*
 * Cleanup allocated memory
 */
int cleanup_veri_preproc()
{
	//fprintf(stderr, "Cleaning up the verilog preprocessor\n");

	veri_define *def_iterator = veri_defines.defined_constants[0];
	veri_include *inc_iterator = veri_includes.included_files[0];
	int i;

	for (i = 0; i < veri_defines.current_index && i < veri_defines.current_size; def_iterator = veri_defines.defined_constants[++i])
	{
		clean_veri_define(def_iterator);
	}
	def_iterator = NULL;
	veri_defines.current_index = 0;
	veri_defines.current_size = 0;
	vtr::free(veri_defines.defined_constants);

	for (i = 0; i < veri_includes.current_index && i < veri_includes.current_size; inc_iterator = veri_includes.included_files[++i])
	{
		clean_veri_include(inc_iterator);
	}
	inc_iterator = NULL;
	veri_includes.current_index = 0;
	veri_includes.current_size = 0;
	vtr::free(veri_includes.included_files);

	//fprintf(stderr, " --- Finished\n");

	return 0;
}

/*
 * Free memory for a symbol in the define table
 */
void clean_veri_define(veri_define *current)
{
	if (current != NULL)
	{
		//fprintf(stderr, "\tCleaning Symbol: %s, ", current->symbol);
		vtr::free(current->symbol);
		//fprintf(stderr, "Value: %s ", current->value);
		vtr::free(current->value);

		current->defined_in = NULL;

		vtr::free(current);
		current=NULL;
		//fprintf(stderr, "...done\n");
	}
}

/*
 * Free memory for a symbol in the include table
 */
void clean_veri_include(veri_include *current)
{
	if (current != NULL)
	{
		//fprintf(stderr, "\tCleaning Include: %s ", current->path);
		vtr::free(current->path);

		vtr::free(current);
		current = NULL;
		//fprintf(stderr, "...done\n");
	}
}

/*
 * add_veri_define returns a non negative value on success, a -1 if creation of the define failed
 * due to a lack of memory and -2 if the symbol was previously defined and the values conflict
 */
int add_veri_define(char *symbol, char *value, int line, veri_include *defined_in)
{
	int i;
	veri_define *def_iterator = veri_defines.defined_constants[0];
	veri_define *new_def = (veri_define *)vtr::malloc(sizeof(veri_define));
	if (new_def == NULL)
	{
		perror("new_def : vtr::malloc ");
		return -1;
	}

	/* Check to see if there's enough space in our lookup table and reallocate if not. */
	if (veri_defines.current_index == veri_defines.current_size)
	{
		veri_defines.defined_constants = (veri_define **)vtr::realloc(veri_defines.defined_constants, (size_t)(veri_defines.current_size * 2) * sizeof(veri_define *));
		//In a perfect world there is a check here to make sure realloc succeded
		veri_defines.current_size *= 2;
	}

	/* Check previously defined values for collisions. */
	for (i = 0; i < veri_defines.current_index && i < veri_defines.current_size; def_iterator = veri_defines.defined_constants[++i])
	{
		if (0 == strcmp(def_iterator->symbol, symbol))
		{
			warning_message(PARSE_ERROR, -1, -1, "The constant %s defined on line %d in %s was previously defined on line %d in %s\n",
				symbol, line, defined_in->path, def_iterator->line, def_iterator->defined_in->path);

			if (value == NULL || (value[0] == '/' && value[1] == '/'))
#ifndef BLOCK_EMPTY_DEFINES
			{
				warning_message(PARSE_ERROR, -1, -1, "The new value of %s is empty\n\n", symbol);
				vtr::free(def_iterator->value);
				def_iterator->value =NULL;
			}
#else
			{
				warning_message(PARSE_ERROR, -1, -1, "The new value of %s is empty, doing nothing\n\n", symbol);
				return 0;
			}
#endif
			else if (0 != strcmp(def_iterator->value, value))
			{
				warning_message(PARSE_ERROR, -1, -1, "The value of %s has been redefined to %s, the previous value was %s\n\n",
					symbol, value, def_iterator->value);
				vtr::free(def_iterator->value);
				def_iterator->value = (char *)vtr::strdup(value);
			}

			vtr::free(new_def);
			return -2;
		}
	}

	/* Create the new define and initalize it. */
	new_def->symbol = (char *)vtr::strdup(symbol);
	new_def->value = (value == NULL)? vtr::strdup("") : (char *)vtr::strdup(value);
	new_def->line = line;
	new_def->defined_in = defined_in;

	veri_defines.defined_constants[veri_defines.current_index] = new_def;
	veri_defines.current_index++;

	return 0;
}

/* add_veri_include shall return NULL if it is unable to create a new
 * veri_include in the lookup table or an entry for that file already exists.
 * Otherwise it wil return a pointer to the new veri_include entry.
 */
veri_include* add_veri_include(const char *path, int line, veri_include *included_from)
{
	int i;
	veri_include *inc_iterator = veri_includes.included_files[0];
	veri_include *new_inc = (veri_include *)vtr::malloc(sizeof(veri_include));
	if (new_inc == NULL)
	{
		perror("new_inc : vtr::malloc ");
		return NULL;
	}

	/* Check to see if there's enough space in our lookup table and reallocate if not. */
	if (veri_includes.current_index == veri_includes.current_size)
	{
		veri_includes.included_files = (veri_include **)vtr::realloc(veri_includes.included_files, (size_t)(veri_includes.current_size * 2) * sizeof(veri_include *));
		//In a perfect world there is a check here to make sure realloc succeded
		veri_includes.current_size *= 2;
	}

	/* Scan previous includes to make sure the file wasn't included previously. */
	for (i = 0; i < veri_includes.current_index && i < veri_includes.current_size && inc_iterator != NULL; inc_iterator = veri_includes.included_files[++i])
		if (0 == strcmp(path, inc_iterator->path))
			warning_message(PARSE_ERROR, line, -1, "Warning: including %s multiple times\n", path);
	

	new_inc->path = vtr::strdup(path);
	new_inc->included_from = included_from;
	new_inc->line = line;

	veri_includes.included_files[veri_includes.current_index] = new_inc;
	veri_includes.current_index++;

	return new_inc;
}

/*
 * Retrieve the value associated, if any, with the given symbol. If the symbol is not present or no
 * value is associated with the symbol then NULL is returned.
 */
char* ret_veri_definedval(const char *symbol)
{
	int is_defined = veri_is_defined(symbol);
	if(0 <= is_defined)
	{
		return veri_defines.defined_constants[is_defined]->value;
	}
	return NULL;

}

/*
 * Returns a non-negative integer if the symbol has been previously defined.
 */
int veri_is_defined(const char * symbol)
{
	int i;
	veri_define *def_iterator = veri_defines.defined_constants[0];

	for (i = 0; (i < veri_defines.current_index) && (i < veri_defines.current_size) && (def_iterator != NULL); i++)
	{
		def_iterator = veri_defines.defined_constants[i];
		if (0 == strcmp(symbol, def_iterator->symbol))
		{
			return i;
		}
	}
	return -1;
}

/*
 * Bootstraps our preprocessor
 */
FILE* veri_preproc(FILE *source)
{
	extern global_args_t global_args;
	extern config_t configuration;
	extern int current_parse_file;
	FILE *preproc_producer = NULL;

	veri_include *veri_initial = add_veri_include(configuration.list_of_file_names[current_parse_file].c_str(), 0, NULL);
	if (veri_initial == NULL)
	{
		fprintf(stderr, "Unable to store include information returning original FILE pointer\n\n");
		return source;
	}

	std::string file_out = 	configuration.debug_output_path 
						+ "/" 
						+ strip_path_and_ext(configuration.list_of_file_names[current_parse_file]).c_str() 
						+ "_preproc.v";

	preproc_producer = fopen(file_out.c_str(), "w+");

	if (preproc_producer == NULL)
	{
		perror("preproc_producer : fdopen - returning original FILE pointer");
		exit(-1);
		return source;
	}

	/* to thread or not to thread, that is the question. Wether yac will block when waitin */
	fprintf(stderr, "Preprocessing verilog.\n");

	veri_preproc_bootstraped(source, preproc_producer, veri_initial);
	rewind(preproc_producer);
	
	return preproc_producer;
}

const char *preproc_symbol_e_STR[] = 
{
	"include",
	"define",
	"undef",
	"ifdef",
	"ifndef",
	"else",
	"endif",
	"preproc_symbol_e_END"
};

enum preproc_symbol_e
{
	PREPROC_INCLUDE,
	PREPROC_DEFINE,
	PREPROC_UNDEF,
	PREPROC_IFDEF,
	PREPROC_IFNDEF,
	PREPROC_ELSE,
	PREPROC_ENDIF,
	preproc_symbol_e_END
};

static preproc_symbol_e get_preproc_directive(const char *in)
{
	preproc_symbol_e to_return = preproc_symbol_e_END;

	if(in && strlen(in) > 0)
	{
		for(int i=0 ; i < (int)preproc_symbol_e_END; i++)
		{
			if(! strcmp(preproc_symbol_e_STR[i], in) )
			{
				to_return = (preproc_symbol_e) i;
				break;
			}
		}
	}
	return to_return;
}

void veri_preproc_bootstraped(FILE *original_source, FILE *preproc_producer, veri_include *current_include)
{

	rewind(original_source);

	int line_number = 1;
	veri_flag_stack *skip = (veri_flag_stack *)vtr::calloc(1, sizeof(veri_flag_stack));

	veri_include *new_include = NULL;

	char *line = NULL;
	buffered_reader_t reader = buffered_reader_t(original_source, "//", "/*", "*/");

	while ((line = reader.get_line()))
	{
		// fprintf(stderr, "%s:%ld\t%s\n", current_include->path,line_number, line);
		if( strlen(line) > 0 )
		{
			std::string proc_line(line);

			// start searching for backticks
			std::size_t pch = proc_line.find_first_of('`') ;

			while ( pch != std::string::npos)
			{			
				std::size_t end_pch = proc_line.find_first_not_of(symbol_char, pch+1);
				if (end_pch != std::string::npos)
				{
					// skip the backtick
					std::string symbol = proc_line.substr(pch+1, (end_pch-pch)-1);

					// verify that this is not a preprocessor directive
					if( get_preproc_directive(symbol.c_str()) == preproc_symbol_e_END)
					{
						// get value from lookup table
						char* value = ret_veri_definedval( symbol.c_str() ) ;
						if (value != NULL)
						{
							proc_line.erase(pch, (end_pch-pch));
							proc_line.insert(pch, value);
						}
					}
				}
							
				// find next backtick
				pch = proc_line.find_first_of('`',  pch+1) ;

			}

			if(! proc_line.empty())
			{
				vtr::free(line);
				line = vtr::strdup(proc_line.c_str());
		
				// fprintf(stderr, "%s:%ld\t%s\n", current_include->path,line_number, line);

				/* Preprocessor directives have a backtick on the first column. */
				if (line[0] == '`')
				{
					char *token = strtok(line, " ");

					// skip the backtick to find the type
					switch( get_preproc_directive(&token[1]) )
					{
						case PREPROC_INCLUDE:
						{
							if(top(skip) < 1)
							{
								/**
								 *  If we encounter an `included directive we want to recurse using included_file and
								 * new_include in place of source and current_include
								 */	

								token = strtok(NULL, "\"");

								std::string current_path = current_include->path;
								auto loc = current_path.find_last_of('/');
								if (loc != std::string::npos) /* No other path to try to find the file */
								{
									current_path = current_path.substr(0,loc+1);
								}
								else
								{
									current_path = "";
								}

								std::string file_path = current_path + token;
								
								FILE* included_file = fopen(file_path.c_str(), "r");
		

								/* If we failed to open the included file handle the error */
								if (!included_file)
								{
									warning_message(PARSE_ERROR, -1, -1, "Unable to open file %s included on line %d of %s\n",
										token, line_number, current_include->path);
									perror("included_file : fopen");
									/*return erro or exit ? */
								}
								else if (NULL != (new_include = add_veri_include(file_path.c_str(), line_number, current_include)))
								{
									printf("Including file %s\n", new_include->path);
									veri_preproc_bootstraped(included_file, preproc_producer, new_include);
								}
								fclose(included_file);
								/* If last included file has no newline an error could result so we add one. */
							}
							break;
						}
						case PREPROC_DEFINE:
						{
							if(top(skip) < 1)
							{
								token = strtok(NULL, " ");
								size_t len = strlen(token);
								char *value = &(token[len+1]);
								
								if(get_preproc_directive(value) != preproc_symbol_e_END)
								{
									printf("Warning! trying to override preprocessor restricted keyword is not allowed\n");
								}
								else
								{
									// symbol value can potentially be to the end of the line!
									add_veri_define(token, value, line_number, current_include);
								}
							}
							break;
						}
						case PREPROC_UNDEF:
						{
							if(top(skip) < 1)
							{
								token = strtok(NULL, " ");
								int is_defined = veri_is_defined(token);
								if(is_defined >= 0)
								{
									clean_veri_define(veri_defines.defined_constants[is_defined]);
									veri_defines.defined_constants[is_defined] = veri_defines.defined_constants[veri_defines.current_index];
									veri_defines.defined_constants[veri_defines.current_index--] = NULL;
								}
							}
							break;
						}
						case PREPROC_IFDEF:
						{
							// if parent is not skipped
							if ( top(skip) < 1 ) 
							{
								token = strtok(NULL, " ");
								int is_defined = veri_is_defined(token);
								if(is_defined < 0) //If we are unable to locate the symbol in the table
								{
									push(skip, 1);
								}
								else
								{
									push(skip, 0);
								}
							}
							// otherwise inherit skip from parent (use 2)
							else 
							{
								push( skip, 2 ) ;
							}
							break;
						}
						case PREPROC_IFNDEF:
						{
							// if parent is not skipped
							if ( top(skip) < 1 ) 
							{
								token = strtok(NULL, " ");
								int is_defined = veri_is_defined(token);
								if(is_defined >= 0) //If we are able to locate the symbol in the table
								{
									push(skip, 1);
								}
								else
								{
									push(skip, 0);
								}
							}
							// otherwise inherit skip from parent (use 2)
							else 
							{
								push( skip, 2 ) ;
							}
							break;
						}
						case PREPROC_ELSE:
						{
							// if skip was 0 (prev. ifdef was 1)
							if(top(skip) < 1)
							{
								// then set to 0
								pop(skip) ;
								push(skip, 1);
							}
							// only when prev skip was 1 do we set to 0 now
							else if (top(skip) == 1)
							{
								pop(skip) ;
								push(skip, 0);
							}
							// but if it's 2 (parent ifdef is 1)
							else 
							{
								// then do nothing
							}
							break;
						}
						case PREPROC_ENDIF:
						{
							pop(skip);
							break;
						}
						default:
						{
							/* Leave unhandled preprocessor directives in place. */
							if (top(skip) < 1)
							{
								fprintf(preproc_producer, "%s %s", line, line + 1 + strlen(line));
							}

							break;
						}
					}
				}
				else if(top(skip) < 1)
				{
					fprintf(preproc_producer, "%s", line);							
				}
			}
		}

		fprintf(preproc_producer,"\n");
		line_number++;
		vtr::free(line);
	}
	vtr::free(skip);
}

/* stack methods ------------------------------------------------------------*/

int top(veri_flag_stack *stack)
{
	if(stack != NULL && stack->top != NULL)
	{
		return stack->top->flag;
	}
	return 0;

}

int pop(veri_flag_stack *stack)
{
	if(stack != NULL && stack->top != NULL)
	{
		veri_flag_node *top = stack->top;
		int flag = top->flag;

		stack->top = top->next;
		vtr::free(top);

		return flag;
	}
	return 0;
}

void push(veri_flag_stack *stack, int flag)
{
	if(stack != NULL)
	{
		veri_flag_node *new_node = (veri_flag_node *)vtr::malloc(sizeof(veri_flag_node));
		new_node->next = stack->top;
		new_node->flag = flag;

		stack->top = new_node;
	}
}
