/*  Copyright 2025 Leuze electronic GmbH + Co. KG
 *
 *  Licensed under the Apache License, Version 2.0
 */

#ifndef LEUZE_ROD_NODE_H
#define LEUZE_ROD_NODE_H

#include <rclcpp/rclcpp.hpp>

#include "leuze_msgs/msg/status_profile_msg_rod.hpp"
#include "leuze_rod_driver/eth_comm_ifc.h"
#include "leuze_rod_driver/eth_comm_rod.h"

const std::string       ROD_DEFAULT_IP_ADDRESS  = "192.168.60.101";     // 192.168.60.101   = default ROD x08 IP address
const std::string       ROD_DEFAULT_PORT        = "3050";               // 3050             = default ROD x08 port
const std::string       ROD_DEFAULT_TOPIC_ID    = "scan1";              // scan1            = default topic name for vizualisation script
const std::string       ROD_DEFAULT_FRAME_ID    = "scanner_laser";      // scanner_laser    = default topic name for vizualisation script

constexpr std::float_t  ROD_DEFAULT_RANGE_MIN   = 0.08;                 // [m]
constexpr std::float_t  ROD_DEFAULT_RANGE_MAX   = 25.0;                 // [m]

constexpr std::int32_t  ROD_LOG_SUPPRESS_TIME   = 60;                   // the same warning / error messages are suppresed by this time [s]

namespace leuze_rod_ros2_drivers
{
    /************************************************************************************************************
     * @class   RodNode
     * 
     * @brief   This class is the ROS node that ensures the whole ROD driver functionality
     ************************************************************************************************************/
    class RodNode : public rclcpp::Node
    {
        public:

            /**
             * @brief constructor
             */ 
            RodNode(std::string ip_addr, std::string port_num, std::string topic_id, std::string frame_id);

            /**
             * @brief deconstructor
             */ 
            ~RodNode();

        private:           

            /* input parameters */
            std::string frame_id_;                                                                              // published scan data frame
            std::string topic_id_;                                                                              // published topic name
            std::string ip_addr_;                                                                               // RODxxx used IP address
            int         port_num_;                                                                              // RODxxx used port number
            
            /* scan data publishing */
            rclcpp::TimerBase::SharedPtr                                scan_publishing_timer_;                 // timer triggering scan data publishing
            rclcpp::Publisher<sensor_msgs::msg::LaserScan>::SharedPtr   scan_publisher_;                        // scan data publisher
            

            /* status data publishing */
            rclcpp::TimerBase::SharedPtr                                        status_publishing_timer_;       // timer triggering status dara refresh and publishing
            rclcpp::Publisher<leuze_msgs::msg::StatusProfileMsgRod>::SharedPtr  status_publisher_;              // status data publisher

            /* Other private structures, variables etc. */
            EthCommIfc*     eth_comm_ifc_;                                                                      // RODxxx common interface 
            RodScanParams   laser_scan_params_;                                                                 // laser scan parameters (given by RODxxx status data at execution time)

            rclcpp::Time    time_last_published_scan_;                                                          // time of last published scan

            std::uint32_t   count_status_failed_;                                                               // coutner of detected status data fails
            rclcpp::Time    time_status_failed_;                                                                // time of last detected status data fail

            rclcpp::Time    time_last_rod_cont_warn_log_;                                                       // time of last RODxxx contamination warning log
            rclcpp::Time    time_last_rod_cont_error_log_;                                                      // time of last RODxxx contamination error log
            rclcpp::Time    time_last_rod_error_log_;                                                           // time of last RODxxx error log
            std::uint32_t   error_last_log_;                                                                    // last logged error code

            /****************************************************************************************************/

            /**
             * @brief get and publish all available scans (if there are any)
             */
            void publishScanData();

            /**
             * @brief refresh and publish ROD status data
             */
            void publishStatusData();

            /****************************************************************************************************/

            void loadConfiguration();

            /****************************************************************************************************/

            /**
             * @brief print header and info about readed parameters
             */
            void logInfoDriverStartup();

            /**
             * @brief print info about used frames and topics
             */
            void logInfoTopicsAndFrame();

            /**
             * @brief print header and info about readed parameters
             */
            void logWarnDebug();

            /**
             * @brief print header and info about readed parameters
             */
            void logWarnSimulation();
    };
}

#endif
