

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/
//_/_/  This file is part of PSYCLONE version 2.1.1.260726 (26 July 2026)
//_/_/  
//_/_/  developed by
//_/_/  
//_/_/  Communicative Machines Ltd. 
//_/_/    http://cmlabs.com/
//_/_/  Copyright (c) 2026
//_/_/  
//_/_/  in collaboration with 
//_/_/  
//_/_/  Icelandic Institute for Intelligent Machines ses
//_/_/    Menntavegur 1
//_/_/    101 Reykjavik
//_/_/    ICELAND
//_/_/    http://www.iiim.is/
//_/_/
//_/_/  PSYCLONE 2.1 is released under the GNU Lesser General Public License 
//_/_/  (LGPL) version 3.0, and is subject to the following
//_/_/  
//_/_/  - CADIA Clause: The license granted in and to the software under this 
//_/_/    agreement is a limited-use license. The software may not be used in 
//_/_/    furtherance of: (i) intentionally causing bodily injury or severe 
//_/_/    emotional harm to any person; (ii) invading the personal privacy or 
//_/_/    violating the human rights of any person; or (iii) committing or 
//_/_/    preparing for any act of war. 
//_/_/    
//_/_/  A commercial license for PSYCLONE 2.1 is also available to 
//_/_/  any interested party from the copyright holder.
//_/_/  
//_/_/  You can redistribute this copy of PSYCLONE 2.1 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.
//_/_/  
//_/_/  You should have received a copy of the GNU General Public License
//_/_/  and the GNU Lesser General Public License along with PSYCLONE 2.1.  
//_/_/  If not, see <http://www.gnu.org/licenses/>.
//_/_/  
//_/_/  PSYCLONE 2.1 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.
//_/_/
//_/_/  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//_/_/  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//_/_/  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
//_/_/  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
//_/_/  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
//_/_/  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
//_/_/  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
//_/_/  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
//_/_/  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
//_/_/  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
//_/_/  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#include "ServiceManager.h"

namespace	cmlabs{

Service::Service() {
	id = 0;
	timeout = 5000;
//	subscription = NULL;
	receiver = NULL;
}

Service::~Service() {
//	delete(subscription);
//	subscription = NULL;
	receiver = NULL;
}

bool Service::receiveHTTPRequest(HTTPRequest* req, NetworkChannel* channel, uint64 conid) {
	delete(req);
	return true;
}

bool Service::receiveMessage(DataMessage* msg, NetworkChannel* channel, uint64 conid) {
	delete(msg);
	return true;
}

bool Service::receiveTelnetLine(TelnetLine* line, NetworkChannel* channel, uint64 conid) {
	delete(line);
	return true;
}









ServiceManager::ServiceManager() {
	lastID = 0;
}

ServiceManager::~ServiceManager() {
	for (uint32 id = 0; id <= lastID; id++)
		delete(services[id]);
	services.clear();
}

bool Service::fromXML(XMLNode &specNode) {

   if (stricmp(specNode.getName(), "service") != 0)
	  return false;

	const char* str;
	if (str = specNode.getAttribute("name"))
		name = str;
	else {
		return false;
	}

	if (str = specNode.getAttribute("rootdir"))
		dir = str;
	if (str = specNode.getAttribute("subdir"))
		subdir = str;
	if (str = specNode.getAttribute("timeout"))
		timeout = utils::Ascii2Uint32(str);

	// subscriptions are handled elsewhere
	//if (specNode.nChildNode()) {
	//	subscription = new Subscription();
	//	if (subscription->fromXML(specNode)) {
	//	}
	//	else {
	//		delete(subscription);
	//		return false;
	//	}
	//}
	return true;
}



bool ServiceManager::init() {
	return true;
}


bool ServiceManager::getServiceID(const char* name, uint32& id) {
	if (stricmp(name, "none") == 0) {
		id = 0;
		return true;
	}
	std::map<uint32, Service*>::iterator it, itEnd;
	for (it = services.begin(), itEnd = services.end(); it != itEnd; it++) {
		if (it->second && stricmp(it->second->name.c_str(), name) == 0) {
			id = it->first;
			return true;
		}
	}
	return false;
}

uint32 ServiceManager::addService(const char* specXML, NetworkReceiver* receiver) {
	XMLResults xmlResults;
	XMLNode	mainNode=XMLNode::parseString(specXML,"service", &xmlResults);
	
	// display error message (if any)
	if (xmlResults.error != eXMLErrorNone)
		return 0;
	return addService(mainNode, receiver);
}

uint32 ServiceManager::addService(XMLNode &specNode, NetworkReceiver* receiver) {
	Service* service = new Service();
	if (!service->fromXML(specNode)) {
		delete(service);
		return 0;
	}
	service->receiver = receiver;

	uint32 id = ++lastID;
	services[id] = service;
	return id;
}

bool ServiceManager::removeService(uint32 id) {
	std::map<uint32, Service*>::iterator it = services.find(id);
	if (it == services.end())
		return true;
	delete(it->second);
	services.erase(it);
	return true;
}


bool ServiceManager::runService(uint32 id, HTTPRequest* req, NetworkChannel* channel, uint64 conid) {
	// find() not operator[]: a request for an unknown service id must not insert
	// a NULL entry (map pollution from arbitrary ids).
	std::map<uint32, Service*>::iterator it = services.find(id);
	Service* service = (it != services.end()) ? it->second : NULL;
	if (!service)
		return false;
	if (service->receiver)
		return service->receiver->receiveHTTPRequest(req, channel, conid);
	else
		return service->receiveHTTPRequest(req, channel, conid);
}

bool ServiceManager::runService(uint32 id, DataMessage* msg, NetworkChannel* channel, uint64 conid) {
	std::map<uint32, Service*>::iterator it = services.find(id);
	Service* service = (it != services.end()) ? it->second : NULL;
	if (!service)
		return false;
	if (service->receiver)
		return service->receiver->receiveMessage(msg, channel, conid);
	else
		return service->receiveMessage(msg, channel, conid);
}

bool ServiceManager::runService(uint32 id, TelnetLine* line, NetworkChannel* channel, uint64 conid) {
	std::map<uint32, Service*>::iterator it = services.find(id);
	Service* service = (it != services.end()) ? it->second : NULL;
	if (!service)
		return false;
	if (service->receiver)
		return service->receiver->receiveTelnetLine(line, channel, conid);
	else
		return service->receiveTelnetLine(line, channel, conid);
}



}
