//! \~\file piintrospection_server.h
//! \~\ingroup Introspection
//! \~\brief
//! \~english Introspection server
//! \~russian Сервер интроспекции
/*
    PIP - Platform Independent Primitives
    Introspection module
    Ivan Pelipenko peri4ko@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.

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

#ifndef PIINTROSPECTION_SERVER_H
#define PIINTROSPECTION_SERVER_H

#ifdef DOXYGEN

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionServer
//! \~\brief
//! \~english Start introspection server with name "name"
//! \~russian Запускает сервер интроспекции с именем "name"
#  define PIINTROSPECTION_START(name)

//! \~\ingroup Introspection
//! \relatesalso PIIntrospectionServer
//! \~\brief
//! \~english Stop introspection server
//! \~russian Останавливает сервер интроспекции
#  define PIINTROSPECTION_STOP

#else

#  if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)

#	include "pipeer.h"

class PIIntrospectionServer;
class PISystemMonitor;

#	define PIINTROSPECTION_SERVER      (PIIntrospectionServer::instance())
#	define PIINTROSPECTION_START(name) PIINTROSPECTION_SERVER->start(#name);
#	define PIINTROSPECTION_STOP        PIINTROSPECTION_SERVER->stop();

//! \~\ingroup Introspection
//! \~\brief
//! \~english Peer-based server that replies to introspection requests for the current process.
//! \~russian Сервер на основе peer, отвечающий на запросы интроспекции для текущего процесса.
class PIP_EXPORT PIIntrospectionServer: public PIPeer {
	PIOBJECT_SUBCLASS(PIIntrospectionServer, PIPeer);

public:
	//! \~english Returns singleton server instance.
	//! \~russian Возвращает экземпляр сервера-синглтона.
	static PIIntrospectionServer * instance();

	//! \~english Starts the server and publishes it under name derived from `server_name`.
	//! \~russian Запускает сервер и публикует его под именем, построенным от `server_name`.
	void start(const PIString & server_name);

	//! \~english Stops the server and releases its system monitor when needed.
	//! \~russian Останавливает сервер и при необходимости освобождает его системный монитор.
	void stop();

private:
	PIIntrospectionServer();
	~PIIntrospectionServer();
	NO_COPY_CLASS(PIIntrospectionServer);

	PIString genName();
	void dataReceived(const PIString & from, const PIByteArray & data) override;
	EVENT_HANDLER(void, sysmonDeleted);

	PRIVATE_DECLARATION(PIP_EXPORT)
	PISystemMonitor * sysmon = nullptr;
	PIMutex sysmon_mutex;
};

#  else
#	define PIINTROSPECTION_START(name)
#	define PIINTROSPECTION_STOP
#  endif

#endif // DOXYGEN

#endif // PIINTROSPECTION_SERVER_H
