#ifndef TCPLOGGER_H
#define TCPLOGGER_H

#include "LoggerConsumerI.h"
#include "ReferenceContainer.h"
#include "EmbeddedServiceMethodBinderI.h"
#include "BasicTCPSocket.h"
#include "SingleThreadService.h"
#include "FastPollingMutexSem.h"
#include "EventSem.h"

namespace MARTe {

struct TcpLogEntry {
    ErrorManagement::ErrorInformation info;
    char8 description[MAX_ERROR_MESSAGE_SIZE];
};

/**
 * @brief Logger consumer that publishes framework logs to TCP and stdout.
 * @details Implements LoggerConsumerI to be used inside a LoggerService.
 */
class TcpLogger : public ReferenceContainer, public LoggerConsumerI, public EmbeddedServiceMethodBinderI {
public:
    CLASS_REGISTER_DECLARATION()

    TcpLogger();
    virtual ~TcpLogger();

    virtual bool Initialise(StructuredDataI & data);

    virtual bool ExportData(StructuredDataI & data);

    /**
     * @brief Implementation of LoggerConsumerI.
     * Called by LoggerService.
     */
    virtual void ConsumeLogMessage(LoggerPage *logPage);

    /**
     * @brief Worker thread method for TCP streaming.
     */
    virtual ErrorManagement::ErrorType Execute(ExecutionInfo & info);

private:
    void InsertLogIntoQueue(const ErrorManagement::ErrorInformation &info, const char8 * const description);

    uint16 port;
    BasicTCPSocket server;
    
    static const uint32 MAX_CLIENTS = 8;
    BasicTCPSocket* activeClients[MAX_CLIENTS];
    FastPollingMutexSem clientsMutex;

    SingleThreadService service;
    ThreadIdentifier workerThreadId;

    static const uint32 QUEUE_SIZE = 1024;
    TcpLogEntry queue[QUEUE_SIZE];
    volatile uint32 readIdx;
    volatile uint32 writeIdx;
    EventSem eventSem;
};

}

#endif
