#include "cloudserver.h"

CloudServer::CloudServer(DispatcherClient * c, const PIByteArray & sname): server(c) {
	setName(sname.toHex());
	server_uuid = sname;
	connects << CONNECTL(c, dataReadedServer, ([this](uint id, PIByteArray & ba) {
							 last_ping.reset();
							 mutex_clients.lock();
							 DispatcherClient * cl = index_clients.value(id, nullptr);
							 mutex_clients.unlock();
							 if (cl) cl->sendData(ba);
						 }));
	connects << CONNECTL(c, pingReceived, [this]() { last_ping.reset(); });
	last_ping.reset();
}


CloudServer::~CloudServer() {}


PIByteArray CloudServer::serverUUID() const {
	return server_uuid;
}


void CloudServer::addClient(DispatcherClient * c) {
	last_ping.reset();
	mutex_clients.lock();
	clients << c;
	uint cid = c->clientId();
	index_clients.insert(cid, c);
	mutex_clients.unlock();
	c->sendConnected(1);
	server->sendConnected(cid);
	CONNECTL(c, dataReaded, ([this, cid](PIByteArray & ba) {
				 //		piCoutObj << c->clientId() << "dataReaded";
				 server->sendDataToClient(ba, cid);
			 }));
}


void CloudServer::removeClient(DispatcherClient * c) {
	last_ping.reset();
	mutex_clients.lock();
	clients.removeOne(c);
	index_clients.remove(c->clientId());
	mutex_clients.unlock();
	server->sendDisconnected(c->clientId());
}


PIVector<DispatcherClient *> CloudServer::getClients() {
	PIMutexLocker locker(mutex_clients);
	PIVector<DispatcherClient *> cl = clients;
	return cl;
}


double CloudServer::lastPing() {
	return last_ping.elapsed_s();
}


void CloudServer::close() {
	server->close();
}


void CloudServer::stop() {
	for (auto c: clients)
		c->close();
	server->stop();
}


void CloudServer::printStatus() {
	PIMutexLocker locker(mutex_clients);
	piCout << "    "
		   << "Clients for" << server->address() << server_uuid.toHex() << ":";
	for (auto c: clients) {
		piCout << "        " << c->address() << c->clientId();
	}
}
