
#pragma once

#include "mqtt/subcriber.hpp"
#include "mqtt/publisher.hpp"
#include "uart/uart.hpp"
#include "3th-part/json.hpp"

struct traffic_light_config
{
    /* data */
    uint16_t id;
    std::string type;
    std::vector<uint16_t> do_addr;
    std::vector<std::string> color;
};

struct roadside_info_config
{
    std::string id;
    std::string topic;
    double longitude;
    double latitude;
    double altitude;
    uint32_t isLight;
};


struct traffic_light_status_config
{
    /* data */
    uint16_t id;
    std::string color;
};

struct traffic_mode_config
{
    uint16_t id;
    std::vector<traffic_light_status_config> lights;
};


class TrafficLightControl
{
public:
    TrafficLightControl(const std::string& id, const std::string& uart);
    TrafficLightControl(nlohmann::json& j);
    ~TrafficLightControl();

    void exec();

    enum LightState
    {
        ALL_OFF = 0,
        RED = 1,
        GREEN = 2,
        YELLOW = 4,
        ALL_ON = 7
    };

    const LightState cvt_light_status(const std::string& status);
    const std::string cvt_light_status(const LightState& status);

    void relay_control(const int channel, const LightState state);

private:
    void init();

    const std::string self_id;

    const std::string uart_name_;

    const bool enable_sim_;
    
    std::shared_ptr<awe::Uart> uart_;

    LightState currnt_lamp_;

    std::shared_ptr<mqtt_dataio::publisher<mqtt_dataio::subscriber_basic::DataBuffer>> __m_light_register_puber;

    std::shared_ptr<mqtt_dataio::publisher<mqtt_dataio::subscriber_basic::DataBuffer>> __m_status_puber;
    std::shared_ptr<mqtt_dataio::subscriber<mqtt_dataio::subscriber_basic::DataBuffer>> __m_control_suber;

    void on_control_request(const mqtt_dataio::subscriber_basic::DataBuffer& msg);

private:
    bool __m_running;

    uint8_t __m_expand_size;
    uint16_t __m_offset_do_addr;
};
