/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2008 OMC Denmark ApS.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//**************************************************************************
//
// BASED ON ACE SAMPLE CODE BY:
//    ACE_wrappers/examples/NT_Service/ntsvc.cpp
//
//**************************************************************************

#include "ntsvc.h"
#include "server.h"

BRUTUS::AutoFinalizer::AutoFinalizer(BRUTUS::NT_Service & service)
	: service_(service)
{
}

BRUTUS::AutoFinalizer::~AutoFinalizer(void)
{
	service_.report_status (SERVICE_STOPPED);
}

BRUTUS::NT_Service::NT_Service(void)
	: brutus_server_(NULL)
{
}

BRUTUS::NT_Service::~NT_Service(void)
{
	delete brutus_server_;
}

// This method is called when the service gets a control request.  It
// handles requests for stop and shutdown by calling terminate ().
// All others get handled by calling up to inherited::handle_control.
void
BRUTUS::NT_Service::handle_control(DWORD control_code)
{
	if ((SERVICE_CONTROL_SHUTDOWN == control_code)
	    || (SERVICE_CONTROL_STOP == control_code)) {
		report_status(SERVICE_STOP_PENDING);

		ACE_DEBUG((LM_INFO, ACE_TEXT("%N:%l - service control stop requested\n")));
		this->brutus_server_->shutdown();
	} else
		inherited::handle_control(control_code);
}

// This is just here to be the target of the notify from above... it
// doesn't do anything except aid on popping the reactor off its wait
// and causing a drop out of handle_events.
int
BRUTUS::NT_Service::handle_exception(ACE_HANDLE)
{
	return 0;
}

int
BRUTUS::NT_Service::handle_timeout(const ACE_Time_Value & tv,
				   const void *)
{
	ACE_UNUSED_ARG(tv);

	return 0;
}

void
BRUTUS::NT_Service::brutus_server(BrutusServer *bs)
{
	this->brutus_server_ = bs;
}

// This is the main processing function for the Service.  It sets up
// the initial configuration and runs the event loop until a shutdown
// request is received.
int
BRUTUS::NT_Service::svc(void)
{
	try {
		AutoFinalizer af(*this);
		report_status(SERVICE_RUNNING);
		this->brutus_server_->svc();
	}
	catch (const CORBA::Exception & ex) {
		ex._tao_print_exception ("TAO NT Naming Service");
		return -1;
	}

	return 0;
}
