#pragma once
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

/**
* @file
* @copyright 2022 MPLv2
*/

#include <cstddef>
#include <cstdint>
#include <memory>
#define ZMQ_BUILD_DRAFT_API 1
#include <zmq.hpp>
#include <string>
#include <vector>
#include <atomic>
#include <thread>

#include <loguru.hpp>


#include <WHISPER/threadSafeQueue.hpp>
#include <WHISPER/Messages/Message.hpp>

/**
  * @brief namespace for all whisper-com related components
  */
namespace WHISPER
{
  // Add datatypes here
  class whispercomm{
    public:     
      whispercomm(std::string id):ownID_(id)
      {};
      void connect(std::shared_ptr<threadSafeQueue<WHISPER::Message>> receiver);
      void publish(std::string msg,std::string topic);
      void disconnect();
      void subscribe(std::string topic);
      void unsubscribe(std::string topic);

      std::string getOwnID();
      // SourceType getOwnDeviceType();

    private: 
      /// device ID
      std::string ownID_;
      /// device ID
           
      /// show if the service is connected or not
      std::atomic<bool> connected;
     
      /// attribute identifying this service as a gateway and all packets should be forwarded
       std::atomic<bool> gateway = false;

      /// variable for holding the receive thread identifier
      std::thread receiveThread;

      /// variable indicating if the receiveThread should be stopped
      std::atomic<bool> stopReceiveThread = false;

      std::shared_ptr<threadSafeQueue<WHISPER::Message>> receiveQueue = nullptr;
      
      std::atomic<bool> Connected = false;

      
      void receive();



    protected:
      
      /// all topics this service subscribed
      std::vector<std::string> subscribedTopics;


      void addMsgToReceiverQueue(WHISPER::Message);
      void setGateway(bool);
      bool isGateway();

      void setConnected(bool val);
      bool isConnected();


      virtual void derivedConnect() = 0;
      virtual void derivedDisconnect() = 0;
      virtual void derivedPublish(std::string msg,std::string topic) = 0;
      virtual void derivedReceive() = 0;

      virtual void derivedSubscribe(std::string topic) = 0;
      virtual void derivedUnsubscribe(std::string topic) = 0;






  };



} // namespace WHISPER