#ifndef __GOLDMODULEMAIN_H
#define __GOLDMODULEMAIN_H

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <iostream>
#include <sstream>
#include <list>
#include <csignal>
#include <chrono>
#include <thread>
#include <ctime>
#include <immintrin.h>
#include <future>
#include <regex>

#include "OSDef.h"
#include "XMLParser.h"
#include "TextData.h"
#include "MDFUtil.h"
#include "GlobalConfig.h"
#include "GlobalDefs.h"

#ifdef __WIN_OS__
#include <Windows.h>
#else
#include <sys/time.h>
#endif 

unsigned long int ulRetEAX = 0;
unsigned long int ulRetEDX = 0;

extern bool testavx1(void);
extern bool testavx2(void);
extern bool testavx512(void);
extern bool testpclmulqdq(void);
extern bool testaes(void); 


XMLParser xd;

// Declare config object
TextData td;

//std::time_t tCurrentTime = std::time(nullptr);
std::time_t tStartTime;
std::time_t tEndTime;
std::time_t tTotalTime;

clock_t start;
clock_t timeElapsed;
unsigned msElapsed;
unsigned msTarget;


std::string sgGoldModuleResultsFile = "AVX_Results.txt";
int igPassFailStatus = 0;  // Default with success
int igPrintConfig = 0;
int igPauseApp = 0;
int igDefaultLoadTimeInMins = 0;
int iColorText = 0;
int iDebugFlag = 0;
int iPrintVersionFlag = 1;
int iPrintSuccessFlag = 1;

int iSec;
int iMin;
int iHour;
int iOptionValid;
int iRun;
int iArgIndex;
//Default time for FMA3 test is 5 seconds
long iAVXtimer = 5;

std::string sgGoldModuleVersion;
std::string strPFOut;


// Prototypes
void Init(void);
void PrintSuccess(void);
void handleArgs(int argc, char *argv[]);
bool is_integer(const std::string & s);
bool isOptionValid(int iArgLocal, int argcLocal, char *argvLocal[], VarType vt);
void PrintColorMsg(std::string sMsg, TextColor iColor);
void PauseWQuit(void);
void PrintVersion(void);
void SignalFun(int iSigNum);
void CleanUp(void);
void WriteResultsFile(int iPassFailStatus);
void HelpUseage(void);
void ReadLocalConfig(void);
void ReadLocalTextConfig(void);

class Timer
{
public:
	Timer();
	~Timer();

	void   StartTimer();          // Start the timer
	void   StopTimer();           // Stop the timer
	double GetTime();             // Get time taken in seconds
	double GetTimeMicroSec();     // get elapsed time in microseconds

private:
	double StartTimeMicSec;       // Timer start time in microseconds
	double EndTimeMicSec;         // Timer end time in microseconds
	int    StopFlag;              // Stop Timer Flag 

#ifdef WIN32	
	LARGE_INTEGER frequency;      // Define the ticks per second
	LARGE_INTEGER startCount;
	LARGE_INTEGER endCount;
#else
	timeval startCount;
	timeval endCount;
#endif
};

typedef union
{
	__int32					m128i_i32[4];
	char						m128i_i8[16];
	__m128i					m128i_a;
	__int64					m128i_i64_[2];
	unsigned __int64		    m128i_u64_[2];
	float                    m256_f32[8];
	//int  m128i_64[0];
}
m128i_;

static const int FirIndex = 1023;
static const int FirIndexRev = 0;
static const int Mask = 0x3FF;
extern bool testavx1();
extern bool testavx2();
extern bool testavx512();
extern bool testpclmulqdq();

#endif  //__GLOBALCONFIG_H
