//where I am
#include "R3_FAFEDE_State.h"
//manager
#include "StateManager.h"
//home
#include "R0_Init_State.h"
//a step after
#include "R4_HEADER_State.h"

//to compute CRC
#include "CRC.h"

//to log something
//#include "Logger.h"

namespace PamOffLineSW
{
extern LogUtil* mainLogUtil;
extern long int iNumCadres; //cadre's number  
extern unsigned long long int iByte_tot;// how many bytes I have read till now	

R3_FAFEDE_State R3_FAFEDE_State::instance;
int R3_FAFEDE_State::posHeaderPKT=2;

R3_FAFEDE_State::R3_FAFEDE_State()
{	
	initHeaderPKT();			
}

R3_FAFEDE_State::~R3_FAFEDE_State()
{
}

void R3_FAFEDE_State::initHeaderPKT()
{
	for(int j=0; j<LENGTH_HEADER_PKT; j++)
	{
		headerPKT[j]=0;
	}
	headerPKT[0]=CODE_FA;
	headerPKT[1]=CODE_FE;
	headerPKT[2]=CODE_DE;
	
	posHeaderPKT=2;
}

void R3_FAFEDE_State::resetHeaderPKT()
{	
	posHeaderPKT=2;
}

void R3_FAFEDE_State::readInput(char inputbyte)
{
//the three bytes before this one are 0xFA 0xFE 0xDE, we want to check if it is a Pamela Packet	
//to do this we read 16 bytes starting from  0xFA and compute the CRC
	posHeaderPKT++;
	headerPKT[posHeaderPKT]=inputbyte;	

	//if we have read all the header	
	if(posHeaderPKT==(LENGTH_HEADER_PKT-1))
	{
		//TODO: maybe if ex_pkt_type_1 != ex_pkt_type_2  the pkt is not good? maybe it shuold be discarded?
		// put this check here and if the pkt must can't be recognised 
		
		//here we check the CRC
		short int CalcCheckSum=(short int)(unsigned char)CM_Compute_CRC16(0, (unsigned char*)&headerPKT, LENGTH_HEADER_PKT-1); 

		//bytes when the PKT starts
		unsigned long long int wherePKT_start=iByte_tot-posHeaderPKT+1;

		//I check also that pkt_type is correct? headerPKT[3]=header[4] ??		
		if ((headerPKT[3]==headerPKT[4])&&(CalcCheckSum==(short int)(unsigned char)(headerPKT[LENGTH_HEADER_PKT-1])))
		{
			//I have found 16 bytes that are a Pamela Packet Header			
			// I will pass it to state R4 and there I will add data to the Packet
			R4_HEADER_State::getInstance().initBufferPKT(headerPKT);
			StateManager::getInstance().changeState(&R4_HEADER_State::getInstance());			
			//just to be sure that always is clean
			initHeaderPKT();
		}
		else
		{	
			stringstream oss;
			oss.str()="Packet Header skipped: ";
			if (headerPKT[3]!=headerPKT[4])
			{
				oss<<"Packet Type mismatch ";			
			}
			else
			{
				oss<<"Packet Header CRC check failed ";				
			}
				
			oss<<"The packet header starts at byte: "<<wherePKT_start<<" in cadre "<<iNumCadres<<" restart the search";			
			string msg = oss.str();
			mainLogUtil->logWarning(msg);
	
			//the 16 bytes analized cannot be considered a correct Header for a Pamela Packet.
			//I want to check if in this 16 bytes I can find a new candidate for a Pam Pkt Header, i.e. a new set of FA FE DE.
			//to do this I go back to the R0 state, and start look for 0xFA				
			resetHeaderPKT();//here I don't clean the buffer with the header
			//change to state R0, it means searching 0xFA
			StateManager::getInstance().changeState(&R0_Init_State::getInstance());
			for(int i=3;i<LENGTH_HEADER_PKT;i++)
			{	
				//I am searching for byte 0xFA, if found I will check if it is the beginning of a new header	
					StateManager::getInstance().getCurrentState()->readInput(headerPKT[i]);		
				}							
			}			
		}			
	}
	
}
