#pragma once
#include "ros_bridge/include/MessageBaseClass.h"
#include "ros_bridge/include/MessageTag.h"
#include "ros_bridge/include/TypeFactory.h"
#include "ros_bridge/include/JsonFactory.h"

#include <memory>
#include "rapidjson/include/rapidjson/document.h"

namespace ROSBridge {

class CasePacker
{
    typedef MessageTag Tag;
    typedef rapidjson::Document JsonDoc;
    typedef std::unique_ptr<JsonDoc> JsonDocUPtr;
public:
    CasePacker();

    template<class T>
    JsonDoc *pack(const T &msg, const std::string &topic)
    {
        JsonDoc *docPt(_jsonFactory.create(msg));
        std::string messageType = T::Group::messageType();
        _addTag(*docPt, topic, messageType.c_str());
        return docPt;
    }

    bool showTag(const JsonDoc &doc, Tag &tag);

    template<class T>
    bool unpack(JsonDoc &doc, T &msg){
        _removeTag(doc);
        return _typeFactory.create(doc, msg);
    }

    static const char* topicKey;
    static const char* messageTypeKey;

protected:
    void _addTag        (JsonDoc &doc,
                         const std::string &topic,
                         const std::string &messageType);
    void _removeTag     (JsonDoc &doc);
    bool _getTopic      (const JsonDoc &doc, std::string &topic);
    bool _getMessageType(const JsonDoc &doc, std::string &messageType);

private:
    TypeFactory _typeFactory;
    JsonFactory _jsonFactory;
};
}

