#include "ros_bridge/include/CasePacker.h"

const char* ROSBridge::CasePacker::topicKey         = "topic";
const char* ROSBridge::CasePacker::messageTypeKey   = "messageType";

ROSBridge::CasePacker::CasePacker(TypeFactory *typeFactory, JsonFactory *jsonFactory) :
    _typeFactory(typeFactory)
  , _jsonFactory(jsonFactory)
{

}

bool ROSBridge::CasePacker::getTag(const JsonDocUPtr &pDoc, Tag &tag) const
{
    if( !getTopic(pDoc, tag.topic()) )
        return false;
    if( !getMessageType(pDoc, tag.messageType()) )
        return false;
    return true;
}

void ROSBridge::CasePacker::addTag(JsonDocUPtr &pDoc, const std::string &topic, const std::string &messageType) const
{
    using namespace ROSBridge;
    using namespace rapidjson;

    {
    // add topic
    rapidjson::Value key(CasePacker::topicKey, pDoc->GetAllocator());
    rapidjson::Value value(topic.c_str(), pDoc->GetAllocator());
    pDoc->AddMember(key, value, pDoc->GetAllocator());
    }

    // add messageType
    rapidjson::Value key(CasePacker::messageTypeKey, pDoc->GetAllocator());
    rapidjson::Value value(messageType.c_str(), pDoc->GetAllocator());
    pDoc->AddMember(key, value, pDoc->GetAllocator());
}

void ROSBridge::CasePacker::addTag(JsonDocUPtr &doc, const ROSBridge::CasePacker::Tag &tag) const
{
    addTag(doc, tag.topic(), tag.messageType());
}

void ROSBridge::CasePacker::removeTag(JsonDocUPtr &pDoc) const
{
    using namespace ROSBridge;
    using namespace rapidjson;
    if ( pDoc->HasMember(CasePacker::topicKey) )
        pDoc->RemoveMember(CasePacker::topicKey);
    if ( pDoc->HasMember(CasePacker::messageTypeKey) )
        pDoc->RemoveMember(CasePacker::messageTypeKey);
}

bool ROSBridge::CasePacker::getTopic(const JsonDocUPtr &pDoc, std::string &topic) const
{
    if (!pDoc->HasMember(CasePacker::topicKey) || !(*pDoc)[CasePacker::topicKey].IsString())
        return false;
    topic = (*pDoc)[CasePacker::topicKey].GetString();
    return true;
}

bool ROSBridge::CasePacker::getMessageType(const JsonDocUPtr&pDoc, std::string &messageType) const
{
    if (!pDoc->HasMember(CasePacker::messageTypeKey) || !(*pDoc)[CasePacker::messageTypeKey].IsString())
        return false;
    messageType = (*pDoc)[CasePacker::messageTypeKey].GetString();
    return true;
}
