#pragma once
// 定义管道引擎 包含队列、运行状态、工作线程、计数器、插件管理器
#include <atomic>
#include <memory>
#include <thread>
#include <utility>
#include <vector>

#include <QHash>
#include <QJsonObject>
#include <QString>

#include "core/plugin_system/PluginManager.h"
#include "core/plugin_system/IProtocolFramerPlugin.h"
#include "core/plugin_system/IProtocolMapperPlugin.h"
#include "core/models/DOMMessage.h"
#include "core/models/EnrichedMessage.h"
#include "core/models/RawBusMessage.h"
#include "core/memory/LockFreeQueue.h"
#include "core/memory/MemoryPool.h"
#include "core/threading/MutexQueue.h"
#include "message_bus/pipeline/DynamicRuleRegistry.h"
#include "message_bus/pipeline/stages/1_framers/PassthroughFramer.h"

namespace softbus::message_bus::pipeline
{

struct SessionKey
{
    std::uint32_t endpointHash{0};
    QString pluginId;

    bool operator==(const SessionKey& other) const
    {
        return endpointHash == other.endpointHash && pluginId == other.pluginId;
    }
};

inline uint qHash(const SessionKey& key, uint seed = 0) noexcept
{
    seed = ::qHash(key.endpointHash, seed);
    return ::qHash(key.pluginId, seed);
}

struct PipelineRuntimeConfig
{
    bool parallelPipeline{false};
    int  parseWorkerCount{2};
    bool orderedEgress{true};

    std::size_t framedQueueMax{4096};
    std::size_t maxReorderDepth{256};
};

struct EndpointFramingState;

class PipelineEngine
{
public:
    struct Counters
    {
        std::atomic<std::uint64_t> in{0};
        std::atomic<std::uint64_t> out{0};
        std::atomic<std::uint64_t> drop{0};
        std::atomic<std::uint64_t> error{0};
        std::atomic<std::uint64_t> mergeDrop{0};
    };

    explicit PipelineEngine(std::size_t queueCapacity = 4096);
    ~PipelineEngine();

    void start();
    void stop();
    void drain();

    bool enqueueIngress(softbus::core::models::RawBusMessage ctx);
    bool enqueueEgress(softbus::core::models::RawBusMessage ctx);

    bool tryPopEgress(softbus::core::models::RawBusMessage& out);
    void setPluginManager(std::shared_ptr<softbus::core::plugin_system::PluginManager> pluginManager);
    void setMemoryPool(std::shared_ptr<softbus::core::memory::MemoryPool> pool);
    void setRuntimeConfig(PipelineRuntimeConfig cfg);
    void loadRuntimeConfigFromJson(const QJsonObject& obj);

    const Counters& counters() const { return m_counters; }

private:
    struct MergeItem
    {
        std::uint32_t    endpointHash{0};
        std::uint64_t    seq{0};
        softbus::core::models::RawBusMessage ctx;
        bool             pipelineOk{false};
    };

    struct MergeState
    {
        std::uint64_t                                            nextExpected{1};
        QHash<std::uint64_t, std::pair<softbus::core::models::RawBusMessage, bool>> buffer;
    };

    void runSingleWorker();
    void parseWorkerLoop();
    void mergerLoop();

    void ensureEndpointFramer(std::uint32_t endpointHash);

    void dispatchFramer(softbus::core::models::RawBusMessage& chunkIn,
                        std::vector<softbus::core::models::RawBusMessage>& completeFramesOut);
    std::uint64_t assignFrameSequence(std::uint32_t endpointHash);
    bool runStages234(const softbus::core::models::RawBusMessage& ctx);
    void ingestMergeItem(MergeItem item);

    std::vector<softbus::core::models::DOMMessage> stage2Parser(const softbus::core::models::RawBusMessage& ctx);
    bool stage3Filter(softbus::core::models::DOMMessage& message);
    bool stage4Validator(const softbus::core::models::DOMMessage& message) const;
    softbus::core::models::EnrichedMessage applyTransformAndEnrich(
        const softbus::core::models::RawBusMessage& rawCtx, softbus::core::models::DOMMessage& message) const;

private:
    softbus::core::memory::LockFreeQueue<softbus::core::models::RawBusMessage> m_ingressQ;
    softbus::core::memory::LockFreeQueue<softbus::core::models::RawBusMessage> m_egressQ;
    std::atomic<bool> m_running{false};
    std::thread       m_worker;
    Counters          m_counters;
    std::shared_ptr<softbus::core::plugin_system::PluginManager> m_pluginManager;
    std::shared_ptr<softbus::core::memory::MemoryPool>           m_pool;

    PipelineRuntimeConfig m_rtConfig;

    std::shared_ptr<softbus::message_bus::pipeline::stages::framers::PassthroughFramer> m_passthroughFramer;
    std::mutex m_framerSessionMutex;
    QHash<SessionKey, std::shared_ptr<softbus::core::plugin_system::IProtocolFramerSession>> m_framerSessions;
    std::mutex m_parserSessionMutex;
    QHash<SessionKey, std::shared_ptr<softbus::core::plugin_system::IProtocolSession>> m_parserSessions;
    std::mutex m_mapperSessionMutex;
    QHash<SessionKey, std::shared_ptr<softbus::core::plugin_system::IProtocolMapperSession>> m_mapperSessions;

    std::mutex                    m_seqMutex;
    QHash<std::uint32_t, std::uint64_t> m_nextFrameSeqByEndpoint;

    std::unique_ptr<softbus::core::threading::MutexQueue<MergeItem>> m_framedQ;
    std::unique_ptr<softbus::core::threading::MutexQueue<MergeItem>>       m_mergeQ;
    std::vector<std::thread>                                                m_parseThreads;
    std::thread                                                             m_mergerThread;

    std::mutex                                              m_endpointMutex;
    QHash<std::uint32_t, std::shared_ptr<EndpointFramingState>> m_endpointFramers;

    std::mutex                 m_mergeStateMutex;
    QHash<std::uint32_t, MergeState> m_mergeByEndpoint;
    int m_count{0}; // 计数器
};

} // namespace softbus::message_bus::pipeline
