/*
    PIP - Platform Independent Primitives
	Introspection module
	Copyright (C) 2016  Ivan Pelipenko peri4ko@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "piintrospection.h"
#include "pisysteminfo.h"


PIIntrospectionContainers::PIIntrospectionContainers() {
	count = 0;
	bytes_allocated = bytes_used = 0;
}


PIIntrospectionThreads::PIIntrospectionThreads() {
}


PIIntrospectionContainers * __PIIntrospectionContainers__::p = 0;
PIIntrospectionThreads * __PIIntrospectionThreads__::p = 0;
PIIntrospectionServer * __PIIntrospectionServer__::p = 0;


void PIIntrospectionThreads::registerThread(int id, short prior, const PIString & name) {
	mutex.lock();
	ThreadInfo & ti(threads[id]);
	ti.id = id;
	ti.priority = prior;
	ti.name = name;
	//piCout << "register thread" << id << name;
	mutex.unlock();
}


void PIIntrospectionThreads::unregisterThread(int id) {
	mutex.lock();
	threads.remove(id);
	mutex.unlock();
}


void PIIntrospectionContainers::containerNew() {
	mutex.lock();
	count++;
	mutex.unlock();
}


void PIIntrospectionContainers::containerDelete() {
	mutex.lock();
	count--;
	mutex.unlock();
}


void PIIntrospectionContainers::containerAlloc(ullong cnt) {
	mutex.lock();
	bytes_allocated += cnt;
	mutex.unlock();
}


void PIIntrospectionContainers::containerFree(ullong cnt) {
	mutex.lock();
	bytes_allocated -= cnt;
	mutex.unlock();
}


void PIIntrospectionContainers::containerUsed(ullong cnt) {
	mutex.lock();
	bytes_used += cnt;
	mutex.unlock();
}


void PIIntrospectionContainers::containerUnused(ullong cnt) {
	mutex.lock();
	bytes_used -= cnt;
	mutex.unlock();
}


PIIntrospectionServer::PIIntrospectionServer(): PIPeer(genName()) {
	CONNECTU(&itimer, tickEvent, this, timerEvent)
			itimer.start(100);
}


PIString PIIntrospectionServer::genName() {
	randomize();
	return "__introspection__server_" + PIString::fromNumber(rand() % 1000);
}


void PIIntrospectionServer::timerEvent() {
	PIByteArray ba;
	PIINTROSPECTION_THREADS->mutex.lock();
	ba << appname << *(PIINTROSPECTION_CONTAINERS) << PIINTROSPECTION_THREADS->threads.values();
	PIINTROSPECTION_THREADS->mutex.unlock();
	//piCout << "send" << appname;
	send("__introspection_client__", ba);
}
