// **********************************************************************
//
// Copyright (c) 2002
// IONA Technologies, Inc.
// Waltham, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef NT_SERVICE_H
#define NT_SERVICE_H

#include <OB/Basic.h>
#include <OB/Logger_fwd.h>

namespace OB 
{

//
// Forward declaration
//
class NTEventLogger;

//
// This class represents an NT service.
//
class NTService
{
    static NTService* instance_; // The one and only instance
    
    CORBA::String_var name_; // The name
    CORBA::String_var title_; // The title
    bool debug_; // Are we debugging?
    DWORD checkPoint_; // Check point value
    SERVICE_STATUS status_; // Status of the service
    SERVICE_STATUS_HANDLE statusHandle_; // Status handle
    NTEventLogger* logger_; // The service logger

    //
    // Subclasses must override start.
    //
    virtual void start(int, char**, Logger_ptr) = 0;

    void control(DWORD);
    void main(int argc, char** argv);

    //
    // Callback for service control
    //
    friend void WINAPI _OB_serviceCtrl(DWORD);

    //
    // Callback for service creation
    //
    friend void WINAPI _OB_serviceMain(DWORD, LPTSTR*);
    
protected:

    //
    // This must be called to update the NT service manager on the
    // state of this service.
    //
    void statusUpdate(DWORD, DWORD = NO_ERROR, DWORD = 0);

public:

    NTService(const char* name, const char* title);
    NTService(const char* name, const char* title, DWORD eventID);

    virtual ~NTService();

    //
    // Get the service instance.
    //
    static NTService* instance();

    //
    // Install the service.
    //
    bool install(bool = false);

    //
    // Uninstall the service.
    //
    bool uninstall();

    //
    // Run the service. This will invoke start() to start the service.
    //
    void run(int, char**);

    //
    // Subclasses must override stop.
    //
    virtual void stop() = 0;

    //
    // Get/set for debug
    //
    void setDebug() { debug_ = true; }
    bool getDebug() const { return debug_; }
};

} // End of namespace OB

#endif
