#pragma once




#include "google/protobuf/any.pb.h"
#include "google/protobuf/message.h"
#include <WHISPER/Messages/Protos/message.pb.h>
#include <cstdint>
#include <memory>
#include <string>
#include <loguru.hpp>


namespace WHISPER {

   enum MsgType : int32_t
    {   
    /// message to shutdown all participants
    SHUTDOWN = 0,
    /// on participant is joined
    JOIN=1,
    /// participant is leaving
    LEAVE,
    /// PING
    PING,
    /// PONG
    PONG,
    /// owntrack informaton
    OWN_TRACK,
    /// raw track message
    RAW_TRACK,
    /// simple data
    SIMPLE
    }; // enum class EventType


    enum MsgTopics : uint32_t
     {
        MANAGEMENT,
        DATA,
        COMMANDS,
        TRACK
     };

    static std::map<MsgTopics, std::string>MsgTopicsMap =
    {
        {MsgTopics::MANAGEMENT, "Management"},
        {MsgTopics::DATA, "Data"},
        {MsgTopics::COMMANDS, "Commands"},
        {MsgTopics::TRACK, "Track"},

    };                 

     enum SourceType : int32_t 
    {   
    SIMCOMTROLER,    
    /// 
    SHIP,
    /// 
    SENSOR,
    /// 
    EFEKTOR,
    /// 
    GATEWAY,
   /// 
    
    
    }; // enum class EventType

    /**
    * @brief the message class is the basic sending an receiving class 
    * it is part of every message an every received string is first deserilized as a Message 
    *
    */
    class Message{  
        private:
            /// the serialized payload
            std::string payloadString_;
            /// shared pointer to the payload protobuf message      
            std::shared_ptr<google::protobuf::Any> payload_; 

        public:
            Message()=default;

            Message(std::int32_t deviceId, MsgTopics topic, MsgType Type,SourceType src);
            Message(std::string msg);

            /**
            * @brief returns the payload string 
            * @return std::string
            */
            std::string getPayloadString();

            ///topic of the message for pub sub
            std::uint32_t topic_;
            /// WHISPER::MsgType ot the payload
            std::int32_t msgType_;
            /// WHISPER::SourceType of the sender
            std::int32_t sourceType_;
            /// id of the sender
            std::int32_t deviceId_;

            /**
            * @brief returns the serialized message
            * @return std::string
            *
            */
            std::string serialize();

            
        protected:    
            /**
            * @brief adds the payload with type of shared_prt of protbuf::any   
            * @param std::shared_ptr<google::protobuf::Any>
            */
            void addPayLoad(std::shared_ptr<google::protobuf::Any> any);
            // void addPayLoad(std::string any);

            /// protobuf message; our header message
            messages::header::Message msg;
           
    };


 





}
