#ifndef ECCBASECLASS_H
#define ECCBASECLASS_H

#include <systemc.h>
#include <tlm.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>

#include "ECC/ECC.h"

#include "../common/xmlAddressdecoder.h"
#include "../common/DebugManager.h"

using namespace std;
using namespace tlm;

class ECCBaseClass : sc_module
{
public:
    struct DataStruct {
        unsigned char *pData;
        unsigned int nDataSize;
    };

private:
    map<unsigned char *, DataStruct> m_mDataPointer;

public:
    // Function prototype for calculated the size of memory needed for saving the encoded data
    // Input nBytes: Number of bytes which have to be encoded
    // Return value: Number of bytes which have to be allocated for storing the encoded data
    virtual unsigned AllocationSize(unsigned nBytes) = 0;

protected:
    // Function prototype for encoding data.
    // Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
    // Result should be written in pDataOut, which has a size of nDataOut.
    // pDataOut is already allocated with a size given by function AllocationEncode
    virtual void Encode(const unsigned char *pDataIn, const unsigned nDataIn,
                        unsigned char *pDataOut, const unsigned nDataOut) = 0;


    // Function prototype for decoding data.
    // Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
    // Result should be written in pDataOut, which has a size of nDataOut.
    // pDataOut is already allocated with a size given by function AllocationDecode
    virtual void Decode(const unsigned char *pDataIn, const unsigned nDataIn,
                        unsigned char *pDataOut, const unsigned nDataOut) = 0;

public:
    tlm_utils::multi_passthrough_target_socket<ECCBaseClass>    t_socket;
    tlm_utils::multi_passthrough_initiator_socket<ECCBaseClass> i_socket;

    SC_CTOR(ECCBaseClass)
        : t_socket("t_socket")
        , i_socket("i_socket")
    {
        t_socket.register_nb_transport_fw(this, &ECCBaseClass::nb_transport_fw);
        i_socket.register_nb_transport_bw(this, &ECCBaseClass::nb_transport_bw);
    }
    // Forward interface
    tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload &trans,
                                        tlm::tlm_phase &phase, sc_time &delay );

    // Backward interface
    tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload &trans,
                                        tlm::tlm_phase &phase, sc_time &delay );
};

#endif // ECCBASECLASS_H
