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

#ifndef LEUZE_ETH_COMM_SIM_H
#define LEUZE_ETH_COMM_SIM_H

#include <string>
#include <vector>

#include <boost/optional.hpp>

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

namespace leuze_rod_ros2_drivers
{
    class EthCommIfc;

    /************************************************************************************************************
     * @class EthCommSim
     * 
     * @brief This class ensures simulation of communication with a ROD scanner 
     ************************************************************************************************************/
    class EthCommSim : public EthCommIfc
    {
        public:

            /****************************************************************************************************/
        
            /**
             * @brief
             */
            EthCommSim();

            /**
             * @brief
             */
            ~EthCommSim();

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

            /**
             * @brief    connect to a ROD scanner and read its setting
             * @param    hostname
             * @param    port  
             * @return   true if success 
             */
            bool connect(const std::string hostname, int port) override;

            /**
             * @brief    close used TCP socket
             * @return   true if success 
             */
            bool closeSocketTCP() override;

            /**
             * @brief    close used UDP socket
             * @return   true if success 
             */
            bool closeSocketUDP() override;

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

            /**
             * @brief    get ROD scanner status
             * @return   return ROD scanner status 
             */
            leuze_msgs::msg::StatusProfileMsgRod getStatusData() override;

            /**
             * @brief    load complete ROD scanner status data
             */
            int readStatusData() override;

            /**
             * @brief    refresh ROD scanner status data
             */
            int refreshStatusData() override;

            /**
             * @brief   send a TCP command
             * @param   cmd_id
             * @return  0 if success
             */
            int sendTcpCmd(std::uint32_t cmd_id) override;

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

            /**
             * @brief    start capturing of TCP measurement packets
             * @return   true if success
             */
            bool startCapturingTCP() override;

            /**
             * @brief    start capturing of UDP measurement packets
             * @return   true if success
             */
            bool startCapturingUDP() override;

            /**
             * @brief    stop capturing of packets
             * @return   state of capturing
             */
            bool stopCapturing() override;

            /**
             * @brief    get packet capturing state
             * @return   state of capturing
             */
            bool getCapturingState() override;

            /****************************************************************************************************/
            
            /**
             * @brief    get scan data
             * @return   scan data 
             */
            ScanData getScan() override;

            /**
             * @brief    get data of full scan
             * @return   full scan data 
             */
            ScanData getCompleteScan() override;

            /**
             * @brief    get number of available scans
             * @return   number of available scans 
             */
            std::size_t getScansAvailable() const override;

            /**
             * @brief    get number of available full scans
             * @return   number of available full scans 
             */
            std::size_t getCompleteScansAvailable() const override;

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

        private:

            std::string hostname_;
            int port_;

            leuze_msgs::msg::StatusProfileMsgRod    rod_status_;
            std::size_t scan_spots_;
            std::chrono::milliseconds scan_period_;
            mutable std::chrono::system_clock::time_point last_scan_time_;
            int scan_length_avg_;
            std::size_t scan_offs_;

            bool state_connected_;
            bool state_capturing_;
    };

} // end namespace leuze_rod_ros2_drivers

#endif // LEUZE_eth_comm_ROD_H
