//
// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include <common/include/CommandHandlerFunctor.hpp>
#include <common/include/CommonProfilingUtils.hpp>
#include <server/include/timelineDecoder/TimelineCaptureCommandHandler.hpp>
#include <server/include/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp>
#include <server/include/timelineDecoder/TimelineDecoder.hpp>

#include <BufferManager.hpp>
#include <armnnUtils/Threads.hpp>
#include <ProfilingService.hpp>
#include <PacketBuffer.hpp>
#include <TimelinePacketWriterFactory.hpp>

#include <doctest/doctest.h>

TEST_SUITE("TimelineDecoderTests")
{
void SendTimelinePacketToCommandHandler(const unsigned char* packetBuffer,
                                        arm::pipe::CommandHandlerFunctor& CommandHandler)
{
    uint32_t uint32_t_size = sizeof(uint32_t);
    unsigned int offset = 0;

    uint32_t header[2];
    header[0] = arm::pipe::ReadUint32(packetBuffer, offset);
    offset += uint32_t_size;
    header[1] = arm::pipe::ReadUint32(packetBuffer, offset);
    offset += uint32_t_size;
    uint32_t PacketDataLength  = header[1] & 0x00FFFFFF;

    auto uniquePacketData = std::make_unique<unsigned char[]>(PacketDataLength);
    std::memcpy(uniquePacketData.get(), packetBuffer + offset, PacketDataLength);

    arm::pipe::Packet packet(header[0], PacketDataLength, uniquePacketData);

    CHECK(std::memcmp(packetBuffer + offset, packet.GetData(), packet.GetLength()) == 0);

    CommandHandler(packet);
}

void PushEntity(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::Entity entity)
{
    model.m_Entities.emplace_back(entity);
}

void PushEventClass(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::EventClass eventClass)
{
    model.m_EventClasses.emplace_back(eventClass);
}

void PushEvent(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::Event event)
{
    model.m_Events.emplace_back(event);
}

void PushLabel(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::Label label)
{
    model.m_Labels.emplace_back(label);
}

void PushRelationship(arm::pipe::TimelineDecoder::Model& model,
                      const arm::pipe::ITimelineDecoder::Relationship relationship)
{
    model.m_Relationships.emplace_back(relationship);
}

TEST_CASE("TimelineDirectoryTest")
{
    uint32_t uint8_t_size  = sizeof(uint8_t);
    uint32_t uint32_t_size = sizeof(uint32_t);
    uint32_t uint64_t_size = sizeof(uint64_t);

    armnn::profiling::BufferManager bufferManager(5);
    armnn::profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);

    std::unique_ptr<armnn::profiling::ISendTimelinePacket> sendTimelinePacket =
            timelinePacketWriterFactory.GetSendTimelinePacket();

    arm::pipe::PacketVersionResolver packetVersionResolver;

    arm::pipe::TimelineDecoder timelineDecoder;
    arm::pipe::TimelineCaptureCommandHandler timelineCaptureCommandHandler(
            1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder);

    arm::pipe::TimelineDirectoryCaptureCommandHandler timelineDirectoryCaptureCommandHandler(
            1, 0, packetVersionResolver.ResolvePacketVersion(1, 0).GetEncodedValue(),
            timelineCaptureCommandHandler, true);

    sendTimelinePacket->SendTimelineMessageDirectoryPackage();
    sendTimelinePacket->Commit();

    std::vector<arm::pipe::SwTraceMessage> swTraceBufferMessages;

    unsigned int offset = uint32_t_size * 2;

    std::unique_ptr<armnn::profiling::IPacketBuffer> packetBuffer = bufferManager.GetReadableBuffer();

    uint8_t readStreamVersion = ReadUint8(packetBuffer, offset);
    CHECK(readStreamVersion == 4);
    offset += uint8_t_size;
    uint8_t readPointerBytes = ReadUint8(packetBuffer, offset);
    CHECK(readPointerBytes == uint64_t_size);
    offset += uint8_t_size;
    uint8_t readThreadIdBytes = ReadUint8(packetBuffer, offset);
    CHECK(readThreadIdBytes == armnn::profiling::ThreadIdSize);
    offset += uint8_t_size;

    uint32_t declarationSize = arm::pipe::ReadUint32(packetBuffer->GetReadableData(), offset);
    offset += uint32_t_size;
    for(uint32_t i = 0; i < declarationSize; ++i)
    {
        swTraceBufferMessages.push_back(arm::pipe::ReadSwTraceMessage(packetBuffer->GetReadableData(),
                                                                      offset,
                                                                      packetBuffer->GetSize()));
    }

    SendTimelinePacketToCommandHandler(packetBuffer->GetReadableData(), timelineDirectoryCaptureCommandHandler);

    for(uint32_t index = 0; index < declarationSize; ++index)
    {
        arm::pipe::SwTraceMessage& bufferMessage = swTraceBufferMessages[index];
        arm::pipe::SwTraceMessage& handlerMessage = timelineDirectoryCaptureCommandHandler.m_SwTraceMessages[index];

        CHECK(bufferMessage.m_Name == handlerMessage.m_Name);
        CHECK(bufferMessage.m_UiName == handlerMessage.m_UiName);
        CHECK(bufferMessage.m_Id == handlerMessage.m_Id);

        CHECK(bufferMessage.m_ArgTypes.size() == handlerMessage.m_ArgTypes.size());
        for(uint32_t i = 0; i < bufferMessage.m_ArgTypes.size(); ++i)
        {
            CHECK(bufferMessage.m_ArgTypes[i] == handlerMessage.m_ArgTypes[i]);
        }

        CHECK(bufferMessage.m_ArgNames.size() == handlerMessage.m_ArgNames.size());
        for(uint32_t i = 0; i < bufferMessage.m_ArgNames.size(); ++i)
        {
            CHECK(bufferMessage.m_ArgNames[i] == handlerMessage.m_ArgNames[i]);
        }
    }
}

TEST_CASE("TimelineCaptureTest")
{
    armnn::profiling::BufferManager bufferManager(50);
    armnn::profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);

    std::unique_ptr<armnn::profiling::ISendTimelinePacket> sendTimelinePacket =
        timelinePacketWriterFactory.GetSendTimelinePacket();

    arm::pipe::PacketVersionResolver packetVersionResolver;

    arm::pipe::TimelineDecoder timelineDecoder;
    const arm::pipe::TimelineDecoder::Model& model = timelineDecoder.GetModel();


    arm::pipe::TimelineCaptureCommandHandler timelineCaptureCommandHandler(
        1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder,
        armnn::profiling::ThreadIdSize);

    using Status = arm::pipe::ITimelineDecoder::TimelineStatus;
    CHECK(timelineDecoder.SetEntityCallback(PushEntity)             == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetEventClassCallback(PushEventClass)     == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetEventCallback(PushEvent)               == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetLabelCallback(PushLabel)               == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);

    const uint64_t entityGuid = 111111u;
    const uint64_t eventClassGuid = 22222u;
    const uint64_t eventClassNameGuid = 22322u;
    const uint64_t timestamp = 33333u;
    const uint64_t eventGuid = 44444u;

    const int threadId = armnnUtils::Threads::GetCurrentThreadId();

    // need to do a bit of work here to extract the value from threadId
    unsigned char* uCharThreadId = new unsigned char[armnn::profiling::ThreadIdSize]();;
    uint64_t uint64ThreadId;

    arm::pipe::WriteBytes(uCharThreadId, 0, &threadId, armnn::profiling::ThreadIdSize);

    if (armnn::profiling::ThreadIdSize == 4)
    {
        uint64ThreadId =  arm::pipe::ReadUint32(uCharThreadId, 0);
    }
    else if (armnn::profiling::ThreadIdSize == 8)
    {
        uint64ThreadId =  arm::pipe::ReadUint64(uCharThreadId, 0);
    }
    delete[] uCharThreadId;

    const uint64_t labelGuid = 66666u;
    std::string labelName = "test_label";

    const uint64_t relationshipGuid = 77777u;
    const uint64_t headGuid = 888888u;
    const uint64_t tailGuid = 999999u;

    for (int i = 0; i < 10; ++i)
    {
        // Send entity
        sendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
        sendTimelinePacket->Commit();
        SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
                                           timelineCaptureCommandHandler);

        // Send event class
        sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid, eventClassNameGuid);
        sendTimelinePacket->Commit();
        SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
                                           timelineCaptureCommandHandler);

        // Send event
        sendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
        sendTimelinePacket->Commit();
        SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
                                           timelineCaptureCommandHandler);

        // Send label
        sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
        sendTimelinePacket->Commit();
        SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
                                           timelineCaptureCommandHandler);

        // Send relationship
        armnn::profiling::ProfilingRelationshipType relationshipType =
            armnn::profiling::ProfilingRelationshipType::DataLink;
        sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
                                                                 relationshipGuid,
                                                                 headGuid,
                                                                 tailGuid,
                                                                 0);
        sendTimelinePacket->Commit();
        SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
                                           timelineCaptureCommandHandler);
    }

    for (unsigned long i = 0; i < 10; ++i)
    {
        CHECK(model.m_Entities[i].m_Guid == entityGuid);

        CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);

        CHECK(model.m_Events[i].m_TimeStamp == timestamp);
        CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
        CHECK(model.m_Events[i].m_Guid == eventGuid);

        CHECK(model.m_Labels[i].m_Guid == labelGuid);
        CHECK(model.m_Labels[i].m_Name == labelName);

        CHECK(model.m_Relationships[i].m_RelationshipType ==
            arm::pipe::ITimelineDecoder::RelationshipType::DataLink);
        CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
        CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
        CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
    }
}

TEST_CASE("TimelineCaptureTestMultipleStringsInBuffer")
{
    armnn::profiling::BufferManager               bufferManager(50);
    armnn::profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);

    std::unique_ptr<armnn::profiling::ISendTimelinePacket> sendTimelinePacket =
                                                        timelinePacketWriterFactory.GetSendTimelinePacket();

    arm::pipe::PacketVersionResolver packetVersionResolver;

    arm::pipe::TimelineDecoder timelineDecoder;
    const arm::pipe::TimelineDecoder::Model& model = timelineDecoder.GetModel();

    arm::pipe::TimelineCaptureCommandHandler timelineCaptureCommandHandler(
        1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder,
        armnn::profiling::ThreadIdSize);

    using Status = arm::pipe::TimelineDecoder::TimelineStatus;
    CHECK(timelineDecoder.SetEntityCallback(PushEntity) == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetEventClassCallback(PushEventClass) == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetEventCallback(PushEvent) == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetLabelCallback(PushLabel) == Status::TimelineStatus_Success);
    CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);

    const uint64_t entityGuid         = 111111u;
    const uint64_t eventClassGuid     = 22222u;
    const uint64_t eventClassNameGuid = 22322u;
    const uint64_t timestamp          = 33333u;
    const uint64_t eventGuid          = 44444u;

    const int threadId = armnnUtils::Threads::GetCurrentThreadId();

    // need to do a bit of work here to extract the value from threadId
    unsigned char* uCharThreadId = new unsigned char[armnn::profiling::ThreadIdSize]();
    uint64_t uint64ThreadId;

    arm::pipe::WriteBytes(uCharThreadId, 0, &threadId, armnn::profiling::ThreadIdSize);

    if ( armnn::profiling::ThreadIdSize == 4 )
    {
        uint64ThreadId = arm::pipe::ReadUint32(uCharThreadId, 0);
    } 
    else if ( armnn::profiling::ThreadIdSize == 8 )
    {
        uint64ThreadId = arm::pipe::ReadUint64(uCharThreadId, 0);
    }
    delete[] uCharThreadId;

    const uint64_t labelGuid  = 66666u;
    std::string    labelName  = "test_label";
    std::string    labelName2 = "test_label2";
    std::string    labelName3 = "test_label32";

    const uint64_t relationshipGuid = 77777u;
    const uint64_t headGuid         = 888888u;
    const uint64_t tailGuid         = 999999u;

    // Check with multiple messages in the same buffer
    for ( int i = 0; i < 9; ++i )
    {
        // Send entity
        sendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
        // Send event class
        sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid, eventClassNameGuid);
        // Send event
        sendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
        // Send label
        sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
        sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName2);
        sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName3);
        // Send relationship
        armnn::profiling::ProfilingRelationshipType relationshipType =
            armnn::profiling::ProfilingRelationshipType::DataLink;
        sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
                                                                 relationshipGuid,
                                                                 headGuid,
                                                                 tailGuid,
                                                                 0);
    }

    sendTimelinePacket->Commit();
    SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
                                       timelineCaptureCommandHandler);

    for ( unsigned long i = 0; i < 9; ++i )
    {
        CHECK(model.m_Entities[i].m_Guid == entityGuid);

        CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);

        CHECK(model.m_Labels[i].m_Guid == labelGuid);

        CHECK(model.m_Events[i].m_TimeStamp == timestamp);
        CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
        CHECK(model.m_Events[i].m_Guid == eventGuid);

        CHECK(model.m_Relationships[i].m_RelationshipType ==
            arm::pipe::ITimelineDecoder::RelationshipType::DataLink);
        CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
        CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
        CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
    }
    for ( unsigned long i = 0; i < 9; i += 3 )
    {
        CHECK(model.m_Labels[i].m_Name == labelName);
        CHECK(model.m_Labels[i+1].m_Name == labelName2);
        CHECK(model.m_Labels[i+2].m_Name == labelName3);
    }
}

}
