#include "CommonUtils.h"
#include "IFIFOWrapper.h"
#include "Message.h"
#include "Logger/Logger.h"
#include "lock.h"
#include "ManagementObjects/DevInfo.h"
#include "ManagementObjects/DevDetail.h"
#include "ManagementObjects/DMAcc.h"
#include "ManagementObjects/WiMAX.h"
#include "ManagementObjects/WiMAXSupp.h"

namespace NS_DM_Client
{
    const String S_inFifoName("ClientAdapterInMessages");
    const String S_outFifoName("ClientAdapterOutMessages");
    const String S_profileInfoSeperator(" ");
    const String S_true("true");
    const String S_false("false");

    const char* S_notificationStatusDescription[] =
    {
        "successful",
        "start",
        "end",
        "failed",
        "abort",
        "authentication",
        "networkFailure",
        "unknown"
    };

    //-------------------------------------------------------------------------------------------

    bool CreateFIFOWrapperEx(IFIFOWrapper*& fifoWrapper, const String& fifoName, bool isForReading, bool isServerSide, bool isBlocked)
    {
        fifoWrapper = CreateFIFOWrapper(isServerSide);
        if (fifoWrapper)
        {
            bool res = (fifoWrapper->Open(fifoName, isForReading, isBlocked) == e_Ok);
            return res;
        }
        return false;
    }
    //-------------------------------------------------------------------------------------------

    bool ReadMessageFromFIFO(IFIFOWrapper* fifoWrapper, Buffer& buffer,
        NS_Logging::Logger& logger, NS_Common::CritSection& criticalSection)
    {
        NS_Common::Lock lock(criticalSection);
        // read header
        size_t headerSize = Message::GetHeaderSize();
        Buffer headerBuffer(headerSize, '\0');
        bool res = (fifoWrapper->Read(headerBuffer) == e_Ok);
        if (!res)
        {
            LOG_ERROR_(logger, "Failed to read header from fifo \"%s\"", S_inFifoName.c_str());
            return res;
        }
        LOG_(logger, "Read header from fifo");
        res = buffer.Allocate(headerSize, '\0');
        memcpy(buffer.GetPointer(), headerBuffer.GetPointer(), headerSize);

        // retrieve body size
        size_t dataSize = Message::GetDataSize();
        size_t bodySize = 0;

        char* body = reinterpret_cast<char*>(headerBuffer.GetPointer());
        body += headerSize - dataSize;
        memcpy(&bodySize, body, dataSize);

        LOG_(logger, "Trying to read body, body size = %d", bodySize);
        if (bodySize != 0)
        {
            Buffer bodyBuffer(bodySize, '\0');
            res = (fifoWrapper->Read(bodyBuffer) == e_Ok);
            if (!res)
            {
                LOG_ERROR_(logger, "Failed to read body from fifo \"%s\"", S_inFifoName.c_str());
                return res;
            }

            buffer.Allocate(buffer.Size() + bodySize, '\0');
            memset(reinterpret_cast<char*>(buffer.GetPointer()) + headerSize, 0, bodySize);
            memcpy(reinterpret_cast<char*>(buffer.GetPointer()) + headerSize, bodyBuffer.GetPointer(), bodySize);
        }
        return res;
    }
    //-------------------------------------------------------------------------------------------

    IMgmtObject* GetMgmtObject(size_t subType)
    {
        IMgmtObject* mgmtObject = (IMgmtObject*)NULL;
        switch (subType)
        {
        case e_devInfo:
            mgmtObject = new(std::nothrow) DevInfo();
            break;
        case e_devDetail:
            mgmtObject = new(std::nothrow) DevDetail();
            break;
        case e_DMAcc:
            mgmtObject = new(std::nothrow) DMAcc();
            break;
        case e_WiMAX:
            mgmtObject = new(std::nothrow) WiMAX();
            break;
        case e_WiMAXSupp:
            mgmtObject = new(std::nothrow) WiMAXSupp();
            break;
        default:
            break;
        }
        return mgmtObject;
    }
    //-------------------------------------------------------------------------------------------

}
