/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 * Interface plugin duy nhất của gói: nguồn mission.
 *
 * Author: DuongTD
 *********************************************************************/
#ifndef MISSION_ADAPTERS_ADAPTER_H_
#define MISSION_ADAPTERS_ADAPTER_H_

#include <memory>
#include <string>
#include <vector>

#include <robot/node_handle.h>

#include <mission_adapters/mission_request.h>
#include <mission_adapters/types.h>

namespace mission_adapters
{
    /// @brief Quan hệ giữa mission mới và hàng đợi đang có.
    enum class SubmitMode
    {
        /// Yêu cầu mới: thay toàn bộ hàng đợi, chặng đang chạy bị preempt (và được bảo dừng).
        kReplace,

        /**
         * Phần nối tiếp của yêu cầu đang chạy: chỉ thêm vào cuối hàng đợi.
         *
         * Đây là hình dạng của VDA5050 order update — phần horizon được release thêm. Xử lý nó như
         * kReplace sẽ huỷ và chạy lại chặng đang đi, dù tuyến đường không hề đổi.
         */
        kAppend
    };

    /// @brief Kết quả chuyển đổi: mission sinh ra và cách chúng vào hàng đợi.
    struct ConversionResult
    {
        std::vector<std::shared_ptr<Mission>> missions;
        SubmitMode mode = SubmitMode::kReplace;

        bool empty() const { return missions.empty(); }
    };

    /**
     * @class MissionSourceAdapter
     * @brief Biến payload của một nguồn cụ thể thành mission của mission layer.
     *
     * Plugin được nạp bằng Boost.DLL theo khoá `library_path` trong YAML, giống mọi plugin khác của
     * workspace. Contract này là public interface qua ranh giới .so: đổi chữ ký thì phải đổi cả
     * registry trong cùng một lần sửa, vì import_alias là dlsym + reinterpret_cast và không có kiểm
     * kiểu nào bắt được sự lệch đó lúc biên dịch.
     *
     * Việc thực thi action KHÔNG thuộc về interface này: adapter chỉ chuyển dữ liệu, navigation
     * runtime mới là nơi chạy action (D8).
     */
    class MissionSourceAdapter
    {
    public:
        using Ptr = std::shared_ptr<MissionSourceAdapter>;

        virtual ~MissionSourceAdapter() = default;

        /**
         * @brief Đọc param riêng của instance. Gọi đúng một lần khi nạp.
         * @param name Tên instance trong `mission_sources` — cũng là namespace param của nó.
         * @param nh   NodeHandle gốc.
         * @return false nếu cấu hình không hợp lệ; registry sẽ báo lỗi và không đăng ký adapter này.
         */
        virtual bool configure(const std::string& name, robot::NodeHandle& nh) = 0;

        /// @brief Schema mà adapter này xử lý. Core định tuyến theo đúng giá trị này.
        virtual std::string schema() const = 0;

        /**
         * @brief Kiểm payload TRƯỚC khi convert.
         * @param[out] reason Lý do từ chối, dùng cho log.
         * @return false -> core từ chối sớm và không đụng vào hàng đợi.
         */
        virtual bool validate(const MissionRequest& request, std::string& reason) const = 0;

        /**
         * @brief Chuyển payload thành 0..n mission, kèm cách chúng vào hàng đợi.
         *
         * Trả rỗng nghĩa là **không có việc**, KHÔNG phải lỗi và cũng không phải lệnh huỷ: core sẽ
         * bỏ qua, giữ nguyên hàng đợi đang chạy (A1).
         */
        virtual ConversionResult convert(const MissionRequest& request) = 0;
    };

} // namespace mission_adapters

#endif  // MISSION_ADAPTERS_ADAPTER_H_
