#pragma once

#include <atomic>
#include <memory>
#include <thread>

#include "core/plugin_system/PluginManager.h"
#include "core/memory/LockFreeQueue.h"
#include "message_bus/pipeline/PipelineContext.h"

namespace softbus::message_bus::pipeline
{

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};
    };

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

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

    bool enqueueIngress(PipelineContext ctx);
    bool enqueueEgress(PipelineContext ctx);

    bool tryPopEgress(PipelineContext& out);
    void setPluginManager(std::shared_ptr<softbus::core::plugin_system::PluginManager> pluginManager);

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

private:
    void run();
    bool stage1Framer(PipelineContext& ctx);
    bool stage2Parser(PipelineContext& ctx);
    bool stage3Filter(PipelineContext& ctx);
    bool stage4Validator(PipelineContext& ctx);

private:
    softbus::core::memory::LockFreeQueue<PipelineContext> m_ingressQ;
    softbus::core::memory::LockFreeQueue<PipelineContext> 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;
};

} // namespace softbus::message_bus::pipeline
