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

#pragma once

#include <armnn/profiling/ILocalPacketHandler.hpp>
#include "DirectoryCaptureCommandHandler.hpp"
#include "IProfilingConnection.hpp"
#include <Packet.hpp>
#include "ProfilingUtils.hpp"
#include "Runtime.hpp"

#include <atomic>
#include <condition_variable>
#include <fstream>
#include <mutex>
#include <queue>
#include <thread>

namespace armnn
{

namespace profiling
{

// forward declaration
class FileOnlyProfilingConnection;

class StreamMetaDataProcessor : public ILocalPacketHandler
{
public:
    explicit StreamMetaDataProcessor(FileOnlyProfilingConnection* fileOnlyProfilingConnection) :
            m_FileOnlyProfilingConnection(fileOnlyProfilingConnection),
            m_MetaDataPacketHeader(ConstructHeader(0, 0)) {};

    std::vector<uint32_t> GetHeadersAccepted() override;

    void HandlePacket(const Packet& packet) override;

private:
    FileOnlyProfilingConnection* m_FileOnlyProfilingConnection;
    uint32_t m_MetaDataPacketHeader;

    static uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness);
};

class FileOnlyProfilingConnection : public IProfilingConnection, public IInternalProfilingConnection
{
public:
    explicit FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions& options)
        : m_Options(options)
        , m_Endianness(TargetEndianness::LeWire)    // Set a sensible default.
                                                    // StreamMetaDataProcessor will set a real value.
        , m_IsRunning(false)
        , m_KeepRunning(false)
        , m_Timeout(1000)
    {
        // add the StreamMetaDataProcessor
        auto streamMetaDataProcessor = std::make_shared<StreamMetaDataProcessor>(this);
        AddLocalPacketHandler(streamMetaDataProcessor);
        // and any additional ones added by the users
        for (const ILocalPacketHandlerSharedPtr& localPacketHandler : options.m_LocalPacketHandlers)
        {
            AddLocalPacketHandler(localPacketHandler);
        }
        if (!m_PacketHandlers.empty())
        {
            StartProcessingThread();
        }
        // NOTE: could add timeout to the external profiling options
    };

    ~FileOnlyProfilingConnection() override;

    bool IsOpen() const override;

    void Close() override;

    // This is effectively receiving a data packet from ArmNN.
    bool WritePacket(const unsigned char* buffer, uint32_t length) override;

    // Sending a packet back to ArmNN.
    Packet ReadPacket(uint32_t timeout) override;

    void SetEndianess(const TargetEndianness& endianness) override //IInternalProfilingConnection
    {
        m_Endianness = endianness;
    }

    void ReturnPacket(Packet& packet) override; //IInternalProfilingConnection

private:
    void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
    void StartProcessingThread();
    void ClearReadableList();
    void DispatchPacketToHandlers(const Packet& packet);

    void Fail(const std::string& errorMessage);

    void ForwardPacketToHandlers(Packet& packet);
    void ServiceLocalHandlers();

    Runtime::CreationOptions::ExternalProfilingOptions m_Options;
    std::queue<Packet> m_PacketQueue;
    TargetEndianness m_Endianness;

    std::mutex m_PacketAvailableMutex;
    std::condition_variable m_ConditionPacketAvailable;

    std::vector<ILocalPacketHandlerSharedPtr> m_PacketHandlers;
    std::map<uint32_t, std::vector<ILocalPacketHandlerSharedPtr>> m_IndexedHandlers;
    std::vector<ILocalPacketHandlerSharedPtr> m_UniversalHandlers;

    // List of readable packets for the local packet handlers
    std::queue<Packet> m_ReadableList;
    // Mutex and condition variable for the readable packet list
    std::mutex m_ReadableMutex;
    std::condition_variable m_ConditionPacketReadable;
    // thread that takes items from the readable list and dispatches them
    // to the handlers.
    std::thread m_LocalHandlersThread;
    // atomic booleans that control the operation of the local handlers thread
    std::atomic<bool> m_IsRunning;
    std::atomic<bool> m_KeepRunning;
    int m_Timeout;
};

}    // namespace profiling

}    // namespace armnn