#ifndef FEC_H
#define FEC_H

#ifdef __cplusplus
extern "C" {
#endif


//#define DBG_SHOW_CHUNKS
//#define DBG_SHOW_PARAMETERS
//#define DBG_SHOW_HEADER
typedef struct {
    unsigned int schemaID;     		//  4 bits
    unsigned int fragmentID;   		//  4 bits
    unsigned int msgID;        		// 16 bits  
    unsigned int etherType;       	// 16 bits
    unsigned int originSize;      	// 13 bits
    unsigned int framgentSize;    	//  8 bits
} fec_header_t;

typedef struct {
    unsigned int receivedOrderNumber; 	//received as which in turn
    unsigned int sentOrderNumber;	//fragmentID
    unsigned int recoveredBitsNumber;	//how many bits where recovered using Hamming
    unsigned int duplicatesReceived;	//number of duplicates
    unsigned int framgentSize;
    bool	 fragmentRecovered;	//was the fragment recovered in the end
    bool 	 fragmentUsed;  	//was the fragment used
    bool	 errorInHeader;		//was the error in FEC header
    
    
} fec_decoder_fragment_raport_t;

typedef struct {
    fec_decoder_fragment_raport_t fragments[8];
    unsigned int 		  bitsRecovered;
    unsigned int 		  fragmentsLost;
    unsigned int 		  fragmentsReceived;
    unsigned int 		  duplicatesReceived;
    bool			  msgRecovered;
    bool			  tooManyFragments;
    
    
} fec_decoder_msg_raport_t;



/* Initialize any buffers / state needed to encode/decode packets */
void fec_open();

/* Free any resources used by the encoder/decoder */
void fec_close();

/* Input: data received from ethernet payload [chunk, chunk+*len)
 * Output:
 *   If cannot (yet) decode, returns 0
 *   Otherwise, returns pointer to decoded message and modifies *len
 *
 * Note: inside be buffers
 */
const unsigned char* fec_decode(const unsigned char* chunk, 	 unsigned int   fragSize, 
				      int*  origMsgSize, unsigned int* origEtherType);

/* Input: ethernet payload to send [chunk, chunk+*len)
 *        index, starts at 0 and incremented each call until done
 * Output:
 *   If no more chunks follow, returns 0
 *   Returns encoded packet and modifies *len
 */
const unsigned char* fec_encode(const unsigned char* chunk, unsigned int* len, int index);



int fec_encoder(const unsigned char*  origMsg,     unsigned int  	 origMsgLen, 
		      unsigned int  origEtherType, const unsigned char** encodedMsgs,
		unsigned int* encodedMsgLen,	   unsigned int*         msg_number);
		
 int erasure_channel(const unsigned char** errorMsgs, 	const unsigned char** encodedMsgs, 
		    unsigned int encodedMsgLen[],	unsigned int msg_number)  ;

int fec_decoder_report();		    
		    
#ifdef __cplusplus
}
#endif

#endif
