/*****************************************************************************/
/*
                                 Watch.h
*/
/*****************************************************************************/

#ifndef WATCH_H_LOADED
#define WATCH_H_LOADED 1

#include "wasd.h"

/**********/
/* macros */
/**********/

/*
   True should cause the compiler to include the module watch statements.
   False should cause the compile to optimize the module statements out.
   This would confer some (perhaps limited) performance benefits.
*/

/* unless otherwise specified the default for category WATCHing is AVAILABLE */
#ifndef WATCH_CAT
#  define WATCH_CAT 1
#endif
/* unless otherwise specified the default for module WATCHing is NONE */
#ifndef WATCH_MOD
#  define WATCH_MOD 0
#endif
/* cannot have WATCH_MOD without WATCH_CAT !!! */
#if WATCH_MOD
#  undef WATCH_CAT
#  define WATCH_CAT 1
#endif

/* call if NULL, does not require dereferencing so NULL is OK */
#define WATCHING(ptr) (ptr == NULL || ptr->WatchItem)

/* if 'ptr' is NULL don't try to dereference it, if not then '->RequestPtr' */
#define WATCHTK(ptr) (ptr == NULL ? (void*)NULL : (void*)ptr->RequestPtr)

#define WATCH_CATEGORY(cat) (WATCH_CAT && (Watch.Category & cat))
#define WATCH_MODULE(mod) (WATCH_MOD && (Watch.Module & mod))

#define WATCH_CONNECT                   0x01
#define WATCH_REQUEST                   0x02
#define WATCH_REQUEST_BODY              0x04
#define WATCH_REQUEST_HEADER            0x08
#define WATCH_RESPONSE                 0x010
#define WATCH_RESPONSE_BODY            0x020
#define WATCH_RESPONSE_HEADER          0x040
#define WATCH_MAPPING                  0x080
#define WATCH_AUTH                    0x0100
#define WATCH_ERROR                   0x0200
#define WATCH_NETWORK                 0x0400
#define WATCH_NETWORK_OCTETS          0x0800
#define WATCH_TIMER                  0x01000
#define WATCH_LOG                    0x02000
#define WATCH_SESOLA                 0x04000
#define WATCH_CGI                    0x08000
#define WATCH_DCL                    0x10000
#define WATCH_DECNET                0x020000
#define WATCH_FILTER                0x040000
#define WATCH_PROXY                 0x080000
#define WATCH_PROXY_REQU_HDR       0x0100000
#define WATCH_PROXY_REQU_BDY       0x0200000
#define WATCH_PROXY_RESP_HDR       0x0400000
#define WATCH_PROXY_RESP_BDY       0x0800000
#define WATCH_PROXY_CACHE         0x01000000
#define WATCH_PROXY_CACHE_MNT     0x02000000
#define WATCH_SPARE_3             0x04000000
#define WATCH_SPARE_2             0x08000000
#define WATCH_SPARE_1             0x10000000
#define WATCH_MATCH               0x20000000
#define WATCH_NOTICED             0x40000000
/* differentiate "category" WATCH items from code "module" WATCH items */
#define WATCH__MODULE             0x80000000 

#define WATCH_MOD_FILE                 (0x01 | WATCH__MODULE)
#define WATCH_MOD_CACHE                (0x02 | WATCH__MODULE)
#define WATCH_MOD_ODS                  (0x04 | WATCH__MODULE)
#define WATCH_MOD_REQUEST              (0x08 | WATCH__MODULE)
#define WATCH_MOD_VM                  (0x010 | WATCH__MODULE)
#define WATCH_MOD_SSI                 (0x020 | WATCH__MODULE)
#define WATCH_MOD_DCL                 (0x040 | WATCH__MODULE)
#define WATCH_MOD_DIR                 (0x080 | WATCH__MODULE)
#define WATCH_MOD_AUTH               (0x0100 | WATCH__MODULE)
#define WATCH_MOD_FAO                (0x0200 | WATCH__MODULE)
#define WATCH_MOD_THROTTLE           (0x0400 | WATCH__MODULE)
#define WATCH_MOD_INSTANCE           (0x0800 | WATCH__MODULE)
#define WATCH_MOD_MAPURL            (0x01000 | WATCH__MODULE)
#define WATCH_MOD_PROXY             (0x02000 | WATCH__MODULE)
#define WATCH_MOD_NET               (0x04000 | WATCH__MODULE)
#define WATCH_MOD_SESOLA            (0x08000 | WATCH__MODULE)
#define WATCH_MOD_CGI               (0x10000 | WATCH__MODULE)
#define WATCH_MOD_ADMIN            (0x020000 | WATCH__MODULE)
#define WATCH_MOD_HTADMIN          (0x040000 | WATCH__MODULE)
#define WATCH_MOD_DECNET           (0x080000 | WATCH__MODULE)
#define WATCH_MOD_UPD             (0x0100000 | WATCH__MODULE)
#define WATCH_MOD_PUT             (0x0200000 | WATCH__MODULE)
#define WATCH_MOD_MSG             (0x0400000 | WATCH__MODULE)
#define WATCH_MOD_SERVICE         (0x0800000 | WATCH__MODULE)
#define WATCH_MOD_CONFIG         (0x01000000 | WATCH__MODULE)
#define WATCH_MOD_METACON        (0x02000000 | WATCH__MODULE)
#define WATCH_MOD_RESPONSE       (0x04000000 | WATCH__MODULE)
#define WATCH_MOD_BODY           (0x08000000 | WATCH__MODULE)
#define WATCH_MOD_SPARE_1        (0x10000000 | WATCH__MODULE)
#define WATCH_MOD__DETAIL        (0x20000000 | WATCH__MODULE)
#define WATCH_MOD__OTHER         (0x40000000 | WATCH__MODULE)
#define WATCH_MOD__RESERVED       0x80000000

/* reserve -1 (0xffffffff) as an easy way to use /WATCH= */
#define WATCH_ONE_SHOT_CAT        0x7fffffff
#define WATCH_ONE_SHOT_MOD        (0x7fffffff & ~WATCH_MOD_FAO)
#define WATCH_ONE_SHOT_ITEM             9999
#define WATCH_ONE_SHOT_DEFAULT_SECONDS   600

/* size of body chunk */
#define WATCH_BODY_CHUNK 96

/*************/
/* structure */
/*************/

typedef struct WatchEnableStruct WATCH_STRUCT;

struct WatchEnableStruct
{
   BOOL  AllRequests,
         Disabled,
         StdoutOnly,
         StdoutToo;
   int  Category,
        Count,
        Module;
   REQUEST_STRUCT  *RequestPtr;
};

/***********************/
/* function prototypes */
/***********************/

WatchBegin (REQUEST_STRUCT*, REQUEST_AST);
BOOL WatchCliParse (char*);
WatchCliSettings ();
WatchData (char*, int);
WatchDataDump (char*, int);
WatchDataFormatted (char*, ...);
WatchDummyReadAst (REQUEST_STRUCT*);
WatchEnd (REQUEST_STRUCT*);
WatchFilter (char*, char*, char*, char*, char*, char*);
char* WatchFunction (void*);
WatchInUse (REQUEST_STRUCT*, BOOL);
WatchPeek (REQUEST_STRUCT*, REQUEST_STRUCT*);
WatchReport (REQUEST_STRUCT*, REQUEST_AST);
WatchReportStruct (REQUEST_STRUCT*, REQUEST_AST);
WatchRequestHeader (char*, int);
char* WatchServerQuotas ();
WatchSetNumber (REQUEST_STRUCT*);
WatchShowEnd (REQUEST_STRUCT*);
WatchShowProcess (REQUEST_STRUCT*, REQUEST_AST, char*, char*);
WatchShowProcessDeleteEnd (REQUEST_STRUCT*);
WatchShowSystem (REQUEST_STRUCT*, REQUEST_AST);
WatchThis (REQUEST_STRUCT*, char*, int, int, char*, ...);
char* WatchWhat (int);

#endif /* WATCH_H_LOADED */

/*****************************************************************************/
