#include <mission_adapters/event.h>

#include <utility>

namespace mission_adapters
{
    // ─────────────────────────────────────────────────────────────────────────
    // EventBus
    // ─────────────────────────────────────────────────────────────────────────

    void EventBus::push(Event event)
    {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            event.sequence = next_sequence_++;
            queue_.push(std::move(event));
        }
        cv_.notify_one();
    }

    void EventBus::pushEmergency(Event event)
    {
        // Bật cờ TRƯỚC khi xếp hàng: bên tiêu thụ thấy được emergency ngay cả khi nó đang bận xử lý
        // một sự kiện khác và chưa quay lại hàng đợi.
        emergency_pending_.store(true, std::memory_order_release);
        push(std::move(event));
    }

    bool EventBus::pop(Event& event)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        cv_.wait(lock, [this] { return stop_ || !queue_.empty(); });

        if (stop_ || queue_.empty()) return false;

        event = std::move(queue_.front());
        queue_.pop();
        return true;
    }

    bool EventBus::takeEmergency()
    {
        return emergency_pending_.exchange(false, std::memory_order_acq_rel);
    }

    bool EventBus::emergencyPending() const
    {
        return emergency_pending_.load(std::memory_order_acquire);
    }

    void EventBus::stop()
    {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            stop_ = true;
        }
        cv_.notify_all();
    }

    void EventBus::reset()
    {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            stop_ = false;
            next_sequence_ = 0;
            queue_ = {};
        }
        emergency_pending_.store(false, std::memory_order_release);
    }

} // namespace mission_adapters
