/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 * Envelope cho payload đầu vào của mission layer.
 *
 * Author: DuongTD
 *********************************************************************/
#ifndef MISSION_ADAPTERS_MISSION_REQUEST_H_
#define MISSION_ADAPTERS_MISSION_REQUEST_H_

#include <memory>
#include <string>

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

namespace mission_adapters
{
    /// @brief Tên schema của các nguồn có sẵn. Nguồn mới tự khai schema riêng, không cần sửa ở đây.
    namespace schema
    {
        constexpr const char* kVda5050Order = "vda5050.order";
        constexpr const char* kPoseStamped  = "geometry.pose_stamped";
    }  // namespace schema

    /**
     * @struct MissionRequest
     * @brief Payload đầu vào cùng với tên schema mô tả nó.
     *
     * Hai nguồn hiện có nhận hai kiểu khác hẳn nhau (Order và PoseStamped) nên không thể có một
     * convert() chung nếu không bọc lại. Core chỉ định tuyến theo @ref schema và không bao giờ cần
     * biết kiểu thật; thêm nguồn mới = thêm schema mới + plugin mới.
     *
     * Payload có kiểu dùng cho nguồn nội bộ (tránh serialize thừa); nguồn ngoài (REST/MQTT/file) đi
     * bằng @ref raw_payload và tự parse trong plugin của mình.
     */
    struct MissionRequest
    {
        std::string schema;

        std::shared_ptr<robot_protocol_msgs::Order>       order;
        std::shared_ptr<robot_geometry_msgs::PoseStamped> pose;

        std::string raw_payload;

        /// @brief Dựng request từ một VDA5050 Order.
        static MissionRequest fromOrder(const robot_protocol_msgs::Order& order)
        {
            MissionRequest request;
            request.schema = schema::kVda5050Order;
            request.order  = std::make_shared<robot_protocol_msgs::Order>(order);
            return request;
        }

        /// @brief Dựng request từ một goal đơn lẻ.
        static MissionRequest fromPose(const robot_geometry_msgs::PoseStamped& pose)
        {
            MissionRequest request;
            request.schema = schema::kPoseStamped;
            request.pose   = std::make_shared<robot_geometry_msgs::PoseStamped>(pose);
            return request;
        }

        /// @brief Dựng request từ payload thô của một nguồn ngoài.
        static MissionRequest fromRaw(const std::string& schema_name, const std::string& payload)
        {
            MissionRequest request;
            request.schema      = schema_name;
            request.raw_payload = payload;
            return request;
        }
    };

} // namespace mission_adapters

#endif  // MISSION_ADAPTERS_MISSION_REQUEST_H_
