//----------------------------------------------------------
// Win32 Service Class
// Written by Christopher Kohlhoff
//
// Declaration of the TService class, a class that
// encapsulates much of the code needed for writing Win32
// services.
//----------------------------------------------------------

#ifndef service_h
#define service_h

#include <classlib/thread.h>

// 
// class TService
// ~~~~~ ~~~~~~~~
// TService is an abstract base class used for implementing
// Win32 services.
//
class TService {
  public:

    // Construction / destruction.
    //
    TService();
    virtual ~TService();

    // Start running as a service.
    //
    bool Start();

    // Start running on the console (for debugging).
    //
    bool Start(int argc, char* argv[]);

    // Add/remove the service to/from the system.
    //
    virtual bool Register();
    virtual bool Unregister();

  protected:

    // Override this function to modify the args to CreateService.
    //
    virtual bool CreateService(SC_HANDLE scm);

    // Override these to provide the name of the service.
    //
    virtual const char* GetName() const = 0;
    virtual const char* GetDisplayName() const = 0;

    // Override this to perform initialisation when service is started.
    //
    virtual bool Init();

    // This function must be overridden to do the service's work.
    //
    virtual void Run() = 0;

    // Override this to perform any cleanup after the service has stopped.
    //
    virtual void Cleanup();

    // Override these to be told when the service is being paused or continued.
    //
    virtual void PauseBegin();
    virtual void PauseEnd();

    // Informs the Service Control Manager of how we are.
    //
    void SetStatus(uint32 status, uint32 error = 0);

    // Checks if we have been asked to pause or stop.
    //
    bool CheckStop();

    // Indicates if we want to stop (return true next time CheckStop is called.
    //
    void SetStop(bool stop);

    // Event logging types
    //
    enum TLogType {
      Error   = EVENTLOG_ERROR_TYPE,
      Warning = EVENTLOG_WARNING_TYPE,
      Info    = EVENTLOG_INFORMATION_TYPE
    };

    // Writes an entry to the system's event log.
    //
    void Log(const char* str, TLogType type = Error);

    // Callback functions for windows.
    //
    virtual void ServiceMain(uint32 argc, char* argv[]);
    virtual void ControlHandler(uint32 control);

    // Command-line arguments passed to the service.
    //
    int ArgC;
    char** ArgV;

  private:

    // Implementation data members.
    //
    TEventSemaphore PauseEvent;
    volatile bool StopFlag;
    SERVICE_STATUS_HANDLE HStatus;
    uint32 StatusCode;
    uint32 ErrorCode;
    HANDLE HEventLog;

    // Disallow assignment and copying.
    //
    TService(const TService&);
    const TService& operator=(const TService&);

  // Callback functions for Windows.
  //
  friend void WINAPI ServiceMain(uint32 argc, char* argv[]);
  friend void WINAPI ControlHandler(uint32 control);
};

#endif