/*****************************************************************************/
/*
                                 MetaCon.h
*/
/*****************************************************************************/

#ifndef METACON_H_LOADED
#define METACON_H_LOADED 1

#include "wasd.h"

/* essentially depth of if-elif-endif nesting */
#define METACON_MAX_FLOW_CONTROL 8

#define METACON_TOKEN_DEFAULT    0
#define METACON_TOKEN_PRE        1
#define METACON_TOKEN_POST       2
#define METACON_TOKEN_TEXT       3
#define METACON_TOKEN_IF         4
#define METACON_TOKEN_ELIF       5
#define METACON_TOKEN_ELSE       6
#define METACON_TOKEN_UNIF       7
#define METACON_TOKEN_IFIF       8
#define METACON_TOKEN_ENDIF      9
#define METACON_TOKEN_SERVICE   10
#define METACON_TOKEN_INCLUDE   11
#define METACON_TOKEN_DIRECTORY 12
#define METACON_TOKEN_CONFIG    13
#define METACON_TOKEN_DICT      14
#define METACON_TOKEN_COMMENT   15
#define METACON_TOKEN_VERSION   16
#define METACON_TOKEN_TEST      17

#define METACON_TYPE_FILE        1
#define METACON_TYPE_CONFIG      2

#define METACON_FLOW_DEFAULT     0
#define METACON_FLOW_IF          1
#define METACON_FLOW_ELIF        2
#define METACON_FLOW_ELSE        3 
#define METACON_FLOW_UNIF        4
#define METACON_FLOW_IFIF        5
#define METACON_FLOW_ENDIF       6

#define METACON_STATE_DEFAULT    0
#define METACON_STATE_BEFORE     1
#define METACON_STATE_NOW        2
#define METACON_STATE_AFTER      3

#define METACON_REPORT_INFORM    1
#define METACON_REPORT_WARNING   2
#define METACON_REPORT_ERROR     3

#define METACON_CONFIG_DIR_LENGTH 127

#define METACON_X509_REQUIRED  1
#define METACON_X509_ABORT     2

/*******************/
/* data structures */
/*******************/

/*
   Store these structures naturally-aligned on AXP.
   Uses a bit more storage but makes access as efficient as possible.
*/

#pragma member_alignment __save
#pragma member_alignment

typedef struct MetaConReportStruct METACON_REPORT;

struct MetaConReportStruct
{
   int  /* number of significant errors */
        ErrorCount,
        /* number of informational reports */
        InformCount,
        /* items in report */
        ItemCount,
        /* length of text in report */
        TextLength,
        /* number of warning reports */
        WarningCount;

   int64  /* revision date/time for source file */
          FileTime64,
          /* date/time file loaded */
          LoadTime64;

   char  /* file name stored locally */
         FileName [ODS_MAX_FILE_NAME_LENGTH+1];

   char  /* pointer to dynamically allocated memory */
         *TextPtr;
};

#define METACON_REGEX_PREG_MAX 3

typedef struct MetaConLineStruct METACON_LINE;

struct MetaConLineStruct
{
   BOOL  ConfigProblem,
         LookupAgentUsed,
         MetaAgentUsed,
         NetAcceptAgentUsed,
         WatchFilter,
         WatchInactive,
         WatchThisOne;

   int  BufferLength,
        BufferSize,
        FlowControlLevel,  /* only used for formatting reports! */
        Length,
        LineNumber,
        MetaFileLevel,     /* only used for formatting reports! */
        MetaFileType,
        Number,
        Size,
        Token,
        VersionNumber;

   void  *LineDataPtr;

   char  *BufferPtr,
         *IncludeFilePtr,
         *InlineTextPtr,
         *TextPtr;

   uchar  VersionCompare [2];

   /* storage for compiled regular expression */
   regex_t  RegexPreg[METACON_REGEX_PREG_MAX];
   regex_t  *RegexPregPtr;
   int  RegexPregCount;
   BOOL  RegexCompiled;

   /* per-rule round-robin count storage */
   unsigned long  RoundRobinCount;

   /* request using the parse functions */
   REQUEST_STRUCT  *RequestPtr;

   /* storage pointed to by above */
   char  Storage[];
};

typedef struct MetaConStruct META_CONFIG;

struct MetaConStruct
{
   BOOL  /* an [IncludeFile] directive was encountered */
         IncludeFile,
         /* a if(lookup_agent:) was encountered */
         LookupAgentUsed,
         /* a if(meta_agent:) was encountered */
         MetaAgentUsed,
         /* a if(accept_agent:) was encountered */
         NetAcceptAgentUsed;

   int  /* number of "lines" in structure */
        LineCount,
        /* total number of logical names translated */
        LnmCount,
        /* current logical name index */
        LnmIndex,
        /* state/flow index during parsing */
        ParseIndex,
        /* used by MetaconReport() to override line/number data */
        ReportLineNumber,
        /* number of bytes allocated to this structure */
        ThisSize;

   int  /* control during parsing */
        ParseFlow [METACON_MAX_FLOW_CONTROL],
        /* control during parsing */
        ParseState [METACON_MAX_FLOW_CONTROL];

   char  /* used by MetaconReport() to override line/number data */
         *ReportLinePtr;

   /* pointers to the various varieties of meta config data */
   void  *AuthMetaPtr,
         *ConfigMetaPtr,
         *InlineMetaPtr,
         *MappingMetaPtr,
         *MsgMetaPtr,
         *ServiceMetaPtr;

   ODS_STRUCT  /* only used during loading to point to the current file */
               *CurrentOdsPtr;

   METACON_REPORT  /* holds report text related to the load */
                   LoadReport;

   METACON_LINE  /* not actually text (to start with) */
                 *ContentPtr,
                 /* the current "line" being parsed */
                 *ParsePtr,
                 /* the next "line" to be parsed */
                 *ParseNextPtr;

   METACON_LINE  /* not actually lines of text remember */
                 Lines[];
};

#pragma member_alignment __restore

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

char* MetaConAgentBegin (REQUEST_STRUCT*);
void MetaConAgentEnd (REQUEST_STRUCT*);
char* MetaConBuffer (METACON_LINE*, char**, int);
BOOL MetaconClientConcurrent (METACON_LINE*, char**, int);
BOOL MetaConCommonRequestHeader (char*);
BOOL MetaConConditionalList (METACON_LINE*, char**, int, char*);
char* MetaConCounter (METACON_LINE*, int);
void* MetaConDatum (REQUEST_STRUCT*, char*, int);
void MetaConDictionary (REQUEST_STRUCT*, char*);
char* MetaConEvaluate (METACON_LINE*);
BOOL MetaConEvaluateClusterMember (METACON_LINE*, char**, int);
BOOL MetaConEvaluateInstance (METACON_LINE*, char**, int);
BOOL MetaConEvaluateTime (METACON_LINE*, char**, int);
BOOL MetaConEvaluateTrnLnm (METACON_LINE*, char**, int);
BOOL MetaConEvaluateRoundRobin (METACON_LINE*, char**, int);
MetaConFree (META_CONFIG**, CALL_BACK);
MetaConInstanceList ();
int MetaConLoad (META_CONFIG**, char*, CALL_BACK, BOOL, BOOL);
MetaConNoteThis (char*);
char* MetaConParse (REQUEST_STRUCT*, META_CONFIG*, METACON_LINE**, int);
METACON_LINE* MetaConParseRaw (META_CONFIG*);
int MetaConReport (META_CONFIG*, int, char*, ...);
MetaConParseReset (META_CONFIG*, BOOL);
BOOL MetaConSetBoolean (META_CONFIG*, char*);
MetaConSetStringList (META_CONFIG*, char*, char**, int*);
int MetaConSetInteger (META_CONFIG*, char*);
char* MetaConShowSeconds (REQUEST_STRUCT*, int);
int MetaConSetSeconds (META_CONFIG*, char*, int);
int MetaConStartupReport (META_CONFIG*, char*);
char* MetaConSubstitute (REQUEST_STRUCT*, char*);
MetaConUnload (META_CONFIG**, CALL_BACK);


#endif /* METACON_H_LOADED */

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

