#pragma once

#include "ros_bridge/rapidjson/include/rapidjson/document.h"
#include "ros_bridge/include/topic_publisher.h"
#include "ros_bridge/include/topic_subscriber.h"
#include "ros_bridge/include/server.h"

#include <memory>
#include <functional>

namespace ros_bridge {
class ROSBridge
{
public:
    typedef rapidjson::Document JsonDoc;
    typedef std::unique_ptr<JsonDoc> JsonDocUPtr;

    explicit ROSBridge();
    explicit ROSBridge(const char* connectionString);
    void publish(JsonDocUPtr doc, const char* topic);
    void subscribe(const char *topic,
                   const std::function<void(JsonDocUPtr)> &callBack);
    void advertiseService(const char* service,
                          const char* type,
                          const std::function<JsonDocUPtr(JsonDocUPtr)> &callback);
    void advertiseTopic(const char* topic,
                        const char* type);

    //! @brief Start ROS bridge.
    void start();
    //! @brief Stops ROS bridge.
    void reset();

    //! @return Returns true if connected to the rosbridge_server, false either.
    //! @note \fn calls start().
    bool connected();
    bool isRunning();

private:
    std::shared_ptr<std::atomic_bool>   _stopped;
    RosbridgeWsClient                   _rbc;
    com_private::TopicPublisher          _topicPublisher;
    com_private::TopicSubscriber         _topicSubscriber;
    com_private::Server                  _server;

};

bool isValidConnectionString(const char* connectionString);
}
