/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 * Thread tiêu thụ event: biến sự kiện từ host thành lời gọi lên MissionManager.
 *
 * Author: DuongTD
 *********************************************************************/
#ifndef MISSION_ADAPTERS_EVENT_PROCESSOR_H_
#define MISSION_ADAPTERS_EVENT_PROCESSOR_H_

#include <atomic>
#include <thread>

#include <robot_geometry_msgs/PoseStamped.h>
#include <robot_protocol_msgs/Order.h>

#include <mission_adapters/event.h>
#include <mission_adapters/mission_manager.h>
#include <mission_adapters/mission_request.h>
#include <mission_adapters/plugin_registry.h>

namespace mission_adapters
{
    /**
     * @class EventProcessor
     * @brief Thread duy nhất biến sự kiện thành thay đổi trạng thái mission.
     *
     * Core không biết adapter nào tồn tại: nó chỉ tra @ref PluginRegistry theo
     * MissionRequest::schema. Thêm một loại nguồn mới = thêm plugin + một dòng YAML, không sửa file
     * nào trong `src/` của gói.
     *
     * Việc chuyển payload -> mission chạy trên đúng thread này (không phải thread của host) vì
     * adapter được phép có state; chuyển đổi trên nhiều thread host sẽ tranh chấp state đó.
     */
    class EventProcessor
    {
    public:
        EventProcessor(MissionManager& mission_manager, PluginRegistry& registry);
        ~EventProcessor();

        void start();
        void stop();

        /**
         * @brief Đường vào chung cho mọi nguồn mission.
         *
         * Nguồn mới chỉ cần dựng MissionRequest với schema của mình rồi gọi hàm này.
         */
        void submitRequest(const MissionRequest& request);

        /// @brief Tiện ích cho nguồn goal đơn lẻ. Chỉ dựng envelope, không biết adapter nào xử lý.
        void goalEvent(const robot_geometry_msgs::PoseStamped& goal);

        /// @brief Tiện ích cho nguồn VDA5050.
        void orderEvent(const robot_protocol_msgs::Order& order);

        void cancelEvent();
        void pauseEvent();
        void resumeEvent();

        /**
         * @brief Báo một chặng đã hoàn tất (nav + action — D8).
         * @param id Mission vừa xong. Bắt buộc: outcome không mang ID sẽ bị manager loại bỏ.
         */
        void navDoneEvent(MissionId id);

        /// @brief Báo một chặng thất bại. Cũng bắt buộc mang MissionId.
        void navFailedEvent(MissionId id);

        void emergencyEvent();
        void clearEmergencyEvent();

    private:
        void spin();
        void process(const Event& event);

        /// Tra adapter theo schema, validate, convert, rồi submit nếu có mission.
        void handleRequest(const MissionRequest& request);

        /// Xử lý emergency đang treo (nếu có) trước khi động tới hàng đợi sự kiện thường.
        void handlePendingEmergency();

        EventBus event_bus_;
        MissionManager& mission_manager_;
        PluginRegistry& registry_;
        std::thread worker_;
        std::atomic<bool> running_{false};
    };

} // namespace mission_adapters

#endif  // MISSION_ADAPTERS_EVENT_PROCESSOR_H_
