void WebSocketSinkManager::addSink(libwebsocket* socket, VehicleProperty::Property property,string uuid)
{
	PropertyList foo = VehicleProperty::capabilities();
	if (!ListPlusPlus<VehicleProperty::Property>(&foo).contains(property))
	{
		DebugOut(DebugOut::Warning)<<"Invalid property requested: "<<property<<endl;
		return;
	}

	QVariantMap reply;

	reply["type"] = "methodReply";
	reply["name"] = "subscribe";
	reply["data"] = property.c_str();
	reply["transactionid"] = uuid.c_str();

	QByteArray replystr;

	if(doBinary)
		replystr = QJsonDocument::fromVariant(reply).toBinaryData();
	else
	{
		replystr = QJsonDocument::fromVariant(reply).toJson();
		cleanJson(replystr);
	}

	lwsWrite(socket, replystr, replystr.length());

	WebSocketSink *sink = new WebSocketSink(m_engine,socket,uuid,property,property);
	m_sinkMap[property].push_back(sink);
}
void WebSocketSinkManager::removeSink(libwebsocket* socket,VehicleProperty::Property property, string uuid)
{
	if (m_sinkMap.find(property) != m_sinkMap.end())
	{
		list<WebSocketSink*> sinks = m_sinkMap[property];

		for(auto i = sinks.begin(); i != sinks.end(); i++)
		{
			delete *i;
		}

		m_sinkMap.erase(property);

		QVariantMap reply;
		reply["type"]="methodReply";
		reply["name"]="unsubscribe";
		reply["data"]=property.c_str();
		reply["transactionid"]= uuid.c_str();

		QByteArray replystr;

		if(doBinary)
			replystr = QJsonDocument::fromVariant(reply).toBinaryData();
		else
		{
			replystr = QJsonDocument::fromVariant(reply).toJson();
			cleanJson(replystr);
		}

		lwsWrite(socket, replystr, replystr.length());
	}
}
void WebSocketSinkManager::addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property, Zone::Type zone, string id)
{
	AsyncPropertyRequest request;
	PropertyList foo = VehicleProperty::capabilities();
	if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(property))
	{
		request.property = property;
	}
	else
	{
		DebugOut(0)<<"websocketsink: Invalid property requested: "<<property;
		return;
	}

	request.zoneFilter = zone;
	request.completed = [socket,id,property](AsyncPropertyReply* reply)
	{
		DebugOut()<<"Got property: "<<reply->property.c_str()<<endl;
		if(!reply->success || !reply->value)
		{
			DebugOut()<<"Property value is null"<<endl;
			delete reply;
			return;
		}

		QVariantMap data;
		data["property"] = property.c_str();
		data["zone"] = reply->value->zone;
		data["value"] = reply->value->toString().c_str();
		data["timestamp"] = reply->value->timestamp;
		data["sequence"] = reply->value->sequence;

		QVariantMap replyvar;

		replyvar["type"]="methodReply";
		replyvar["name"]="get";
		replyvar["data"]= data;
		replyvar["transactionid"]=id.c_str();

		QByteArray replystr;

		if(doBinary)
			replystr = QJsonDocument::fromVariant(replyvar).toBinaryData();
		else
		{
			replystr = QJsonDocument::fromVariant(replyvar).toJson();
			cleanJson(replystr);
		}

		lwsWrite(socket, replystr, replystr.length());

		delete reply;
	};

	AsyncPropertyReply* reply = routingEngine->getPropertyAsync(request);
}
void WebSocketSinkManager::setValue(libwebsocket* socket,VehicleProperty::Property property,string value,Zone::Type zone,string uuid)
{
	AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(property,value);

	AsyncSetPropertyRequest request;
	request.property = property;
	request.value = type;
	request.zoneFilter = zone;
	request.completed = [&](AsyncPropertyReply* reply)
	{
		QVariantMap data;
		data["property"] = property.c_str();
		data["zone"] = zone;
		data["source"] = reply->value->sourceUuid.c_str();

		QVariantMap replyvar;
		replyvar["type"]="methodReply";
		replyvar["name"]="set";
		replyvar["data"]= data;
		replyvar["transactionid"]=uuid.c_str();

		QByteArray replystr;

		if(doBinary)
			replystr = QJsonDocument::fromVariant(replyvar).toBinaryData();
		else
		{
			replystr = QJsonDocument::fromVariant(replyvar).toJson();
			cleanJson(replystr);
		}

		lwsWrite(socket, replystr, replystr.length());

		delete reply;
	};

	m_engine->setProperty(request);
	DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "AbstractRoutingEngine::setProperty called with arguments:" << property << value << "\n";
	delete type;

}
//Called when a client connects, subscribes, or unsubscribes.
void WebSocketSource::checkSubscriptions()
{
	while (queuedRequests.size() > 0)
	{
		VehicleProperty::Property prop = queuedRequests.front();
		removeOne(&queuedRequests,prop);
		if (contains(activeRequests,prop))
		{
			return;
		}
		activeRequests.push_back(prop);

		QVariantMap reply;

		reply["type"] = "method";
		reply["name"] = "subscribe";
		reply["property"] = prop.c_str();
		reply["transactionid"] = "d293f670-f0b3-11e1-aff1-0800200c9a66";

		lwsWriteVariant(clientsocket, reply);
	}
}