/*
 * sr-api.h,v 1.1 1994/01/28 17:05:43 franktor Exp
 *
 * sr-api.h
 *
 * Copyright (c) 1992 Nordic SR-NET
 * Geir Pedersen, Geir.Pedersen@usit.uio.no
 *
*/

#ifndef SR_API_H
#define SR_API_H

#ifndef VMS
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <sr-general.h>
#else
#include <sys/types.h>
#if defined(_TYPES_) /* Incompatibility from Wollongong */
#define __STDDEF_LOADED 1
#define __TYPES_LOADED	1
#define __STAT_LOADED	1
#define __SOCKET_TYPEDEFS	1
#endif
#ifndef ITIMER_REAL
#include <sys/time.h>		/* This idiot cannot be doubly included */
#endif
#include <stdio.h>
#include <sr-general.h>
#include <sr-oid.h>
#endif
#include <sr-address.h>

#ifdef VMS
#define u_int unsigned int
#endif

typedef enum LowerLayerKind { llkISODE, llkTCPIP } LowerLayerKind; 

typedef enum externEncodeType { extEncANY, extEncOctetString, extEncBitString } externEncodeType;   

#if 0
Oid	str2Oid		ARGDCL (( const char * ));
char *	Oid2str		ARGDCL (( Oid, int /* protocol = 1 or 2 */ ));
Oid	Oiddup		ARGDCL (( Oid ));
int	Oidcmp		ARGDCL (( Oid, Oid ));
void	Oidfree		ARGDCL (( Oid ));
Boolean	isNullOid	ARGDCL (( Oid ));
#endif

typedef struct EXTERN {
   Oid			directReference;	/* OPTIONAL */
   int		     	*indirectReference;	/* OPTIONAL */
   octetString		*dataValueDescriptor;	/* OPTIONAL */

   externEncodeType	externEncoding;
   /*   void		*ANY;*/
   octetString		*octStr;
   /*   void		*bitStr;*/
} EXTERN;

struct 			RPNQuery;
struct 			RPNStructure;
enum 			RPNStructureType;


#define SR_ATTRSET_BIB1		"1.1.10163.3.1"
#define Z3950_ATTRSET_BIB1	"1.2.840.10003.3.1"

/* Handling of attribute and diagnostic sets */

#define SR_DIAGSET_BIB1		"1.1.10163.4.1"
#define Z3950_DIAGSET_BIB1	"1.2.840.10003.4.1"

struct DiagRec;			/* forward decl */

Boolean loadDiagnosticSet ( char *fromFile );
struct DiagRec *newDiagRec ( Oid diagSet, int condition, char *addinfo );
char *diagRec2Str ( struct DiagRec*, Boolean includeSetName );


/* Handling of presentation contexts */

typedef struct presContext { 
   Oid			abstractSyntax;
   Oid			transferSyntax;
   int			PCI;	
   Boolean		accepted; /* used during PC negotiation */
   struct presContext 	*next;	/* next in set */
   void			*userHook;
} presContext;

presContext *newPC ( Oid AS, Oid TS, int PCI );
presContext *addPC ( presContext *PClist, presContext *PC );
presContext *subPC ( presContext *PClist, presContext *PC );
presContext *dupPClist ( presContext *PClist );
void freePClist ( presContext *PClist );
Boolean isPCin ( presContext *PClist, presContext *PC );
presContext *findPCI ( presContext *PClist, int PCI );
char *PC2str ( presContext *PC );


/* Initialise REQUEST AND RESPONSE */

				/* options */
#define OPT_SEARCH	1
#define OPT_PRESENT	2
#define OPT_DELSET	4

				/* Protocol version */
#define PROTO_V1	1
#define PROTO_V2	2

typedef struct Authentication {
   octetString		*user;
   octetString		*password;
   octetString		*account; /* optional */
} Authentication;


typedef struct SRInitialiseRequest {
   u_int		protocolVersion;
   u_int		options;
   int			preferredMessageSize;
   int			maximumMessageSize;
   Authentication	*authentication;
   char			*implementationId;
   char			*implementationName;
   char			*implementationVersion;
   EXTERN		*userInformationField;
} SRInitialiseRequest;


typedef struct SRInitialiseResponse {
   u_int		protocolVersion;
   u_int		options;
   int			preferredMessageSize;
   int			maximumMessageSize;
   Boolean		initializationStatus;
   char			*implementationId;
   char			*implementationName;
   char			*implementationVersion;
   EXTERN		*userInformationField;
} SRInitialiseResponse;



/* SEARCH REQUEST AND RESPONSE */


typedef enum queryType { queryPrivate=2, queryRpnQuery=0, queryIso8777Query=1 } queryType;

typedef struct Query {
   queryType		kind;
   union {
      struct RPNQuery	*rpnQuery;
      octetString	*iso8777Query;
   } q;
} Query;

typedef struct RPNQuery {
   Oid			attributeSetId;
   struct RPNStructure	*rpnStructure;
} RPNQuery;

typedef struct AttributeElement {
   u_int		attributeType;
   u_int		attributeValue;
} AttributeElement;

typedef struct AttributeList {
   AttributeElement	*attrElem;
   struct AttributeList *next;
} AttributeList;

typedef struct AttributesPlusTerm {
   struct AttributeList		*attributeList;
   octetString		      	*term;
   struct AttributesPlusTerm 	*next;
} AttributesPlusTerm;

typedef enum operandType { operandAttrsPlusTerm, operandResultSet } operandType;  

typedef struct Operand {
   operandType		kind;
   AttributesPlusTerm	*attrsPlusTerm;
   char			*resultSetId;
} Operand;

typedef enum RPNStructureType { rpnOpr, rpnSeq } RPNStructureType;

typedef enum Operator { operatorAnd=0, operatorOr=1, operatorAndNot=2 } Operator;

typedef struct RPNStructure {
    RPNStructureType 	kind;
    union {
       Operand		*operand;
       struct {
	  struct RPNStructure	*rpnStructure1;
	  struct RPNStructure	*rpnStructure2;
	  Operator	operator;
       } s;
    } u;
} RPNStructure;


typedef struct DiagRec {
   Oid			diagnosticSetId;
   u_int		condition;
   char			*addinfo;
} DiagRec;

typedef struct NamePlusRecord {
   char 		*databaseName;
   enum {nprRecord=1, nprDiag=2} nprKind; 
   union {
      EXTERN		*databaseRecord;
      DiagRec 		*surrogateDiagnostic;
   } u;
   struct NamePlusRecord *next;
} NamePlusRecord;

typedef enum RecordKind {
  recNamePlusRecord = 1, recDiagRec = 2
} RecordKind;

typedef struct Records {
   RecordKind recKind; 
   union {
      NamePlusRecord  	*databaseOrSurDiagnostics;
      DiagRec		*nonSurrogateDiagnostic;
   } u;
} Records;

typedef enum ResultSetStatus { resultSetStatus_ignore=0, resultSetStatus_subset=1, resultSetStatus_interim=2,
			       resultSetStatus_none=3 } ResultSetStatus;

typedef struct RCNameAndId {
   char			*databaseName;
   char			*recordCompositionId;
   struct RCNameAndId	*next;
} RCNameAndId;

typedef struct RecordComposition {
   Boolean		genericRecordComposition;
   union {
      RCNameAndId	*databaseSpecific;
      char		*generic;
   } u;
} RecordComposition;

typedef enum PresentStatus { presentStatus_ignore=(-1),presentStatus_success=0, presentStatus_partial_1=1,
			     presentStatus_partial_2=2, presentStatus_partial_4=4,
			     presentStatus_failure=5 
			     } PresentStatus;

typedef struct SRSearchRequest {
   int			smallSetUpperBound;
   int			largeSetLowerBound;
   int			mediumSetPresentNumber;
   Boolean		replaceIndicator;
   char			*proposedResultSetId;
   char			**databaseId;
   int			noDatabaseIds;
   RecordComposition	*smallSetRecordComposition;
   RecordComposition	*mediumSetRecordComposition;
   Oid			preferredRecordSyntax;
   Query		*query;
} SRSearchRequest;


typedef struct SRSearchResponse {
   int			numberOfRecordsFound;
   int			numberOfRecordsReturned;
   int			nextResultSetPosition;
   Boolean		searchStatus;
   ResultSetStatus	resultSetStatus;
   PresentStatus	presentStatus;
   Records 		*records;
} SRSearchResponse;


/* PRESENT REQUEST AND RESPONSE */


typedef struct SRPresentRequest {
   char			*resultSetId;
   int			resultSetStartPoint;
   int			numberOfRecordsRequested;
   RecordComposition	*recordComposition;
   Oid			preferredRecordSyntax;
} SRPresentRequest;


typedef struct SRPresentResponse {
   int			numberOfRecordsReturned;
   int			nextResultSetPosition;
   PresentStatus 	presentStatus;
   Records		*records;
} SRPresentResponse;


/* DELETE RESULT SET REQUEST AND RESPONSE */


typedef enum DeleteSetFunction { deleteSetFunction_list=0,
				 deleteSetFunction_all=1 } DeleteSetFunction;  

typedef struct ResultSetList {
   char			*resultSetId;
   struct ResultSetList	*next;
} ResultSetList;

typedef enum DeleteSetStatus {
   deleteSetStatus_success			= 0,
   deleteSetStatus_resultSetDidNotExist		= 1,	
   deleteSetStatus_previouslyDeletedByTarget	= 2,
   deleteSetStatus_systemProblemAtTarget	= 3,
   deleteSetStatus_accessNotAllowed		= 4,
   deleteSetStatus_resourceControl		= 6,
   deleteSetStatus_bulkDeleteNotSupported	= 7,
   deleteSetStatus_notAllResultSetDeletedOnBulkDelete = 8,
   deleteSetStatus_notAllResultSetsDeleted	= 9
} DeleteSetStatus;

typedef struct ListStatuses {
   char			*resultSetId;
   DeleteSetStatus	deleteSetStatus;
   struct ListStatuses	*next;
} ListStatuses;
   

typedef struct SRDeleteResultSetRequest {
   DeleteSetFunction	deleteSetFunction;
   ResultSetList	*resultSetList;
} SRDeleteResultSetRequest;

typedef struct SRDeleteResultSetResponse {
   DeleteSetStatus	deleteOperationStatus;
   ListStatuses		*deleteListStatuses;
   int			numberNotDeleted; /* -1 signals UNKNOWN (value is OPTIONAL) */
   ListStatuses		*bulkStatuses;
   char			*deleteMessage;
} SRDeleteResultSetResponse;


/* CLOSE REQUEST AND RESPONSE */

typedef struct SRCloseRequest {
   char			filler;	/* some compilers barf on an empty struct */
} SRCloseRequest;

typedef struct SRCloseResponse {
   Boolean		closeAccepted;
} SRCloseResponse;


/* PROCEDURAL INTERFACE */

/*typedef enum LogLevel { logTrace, logDebug, logExceptions, logNotice, logAll } LogLevel;*/

Boolean OSI_Initialise ( LogLevel logLevel, FILE *log );
Boolean OSI_Verify ( void );
void OSI_Close ( void );
void Oid_Initialise ( void );

fd_set *SR_GetSelectFD_SET ( void );

char *OSI_LastError ( void  );

Boolean SR_OpenAssociation ( SR_Address *to, presContext **pci, int *ref );
Boolean SR_CreateListener ( SR_Address *where, Boolean (*accept)( int COMMA_PM_LLK_ARG(LowerLayerKind), presContext *pci ) );
Boolean SR_VerifyAssociation ( int ref );
Boolean SR_AbortAssociation ( int ref );

typedef enum SROperation { oprNone, oprInitialiseRequest, oprInitialiseResponse, oprSearchRequest,
			      oprSearchResponse, oprPresentRequest, oprPresentResponse,
			      oprDeleteResultSetRequest, oprDeleteResultSetResponse,
			      oprCloseRequest, oprCloseResponse, oprAbort } SROperation;

char *sro2str ( SROperation sro );

SROperation SR_PollNetwork ( struct timeval *timeout, int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, int *ref );

Boolean SR_SendInitialiseRequest ( int ref, SRInitialiseRequest *irq );
Boolean SR_SendInitialiseResponse ( int ref, SRInitialiseResponse *irp );
SRInitialiseRequest *SR_ReadInitialiseRequest ( int ref );
SRInitialiseResponse *SR_ReadInitialiseResponse ( int ref );

Boolean SR_SendSearchRequest (  int ref, SRSearchRequest *irq );
Boolean SR_SendSearchResponse ( int ref, SRSearchResponse *irp );
SRSearchRequest *SR_ReadSearchRequest ( int ref  );
SRSearchResponse *SR_ReadSearchResponse ( int ref );

Boolean SR_SendPresentRequest ( int ref, SRPresentRequest *irq );
Boolean SR_SendPresentResponse ( int ref, SRPresentResponse *irp );
SRPresentRequest *SR_ReadPresentRequest ( int ref  );
SRPresentResponse *SR_ReadPresentResponse ( int ref );

Boolean SR_SendDeleteResultSetRequest ( int ref, SRDeleteResultSetRequest *irq );
Boolean SR_SendDeleteResultSetResponse ( int ref, SRDeleteResultSetResponse *irp );
SRDeleteResultSetRequest *SR_ReadDeleteResultSetRequest ( int ref );
SRDeleteResultSetResponse *SR_ReadDeleteResultSetResponse ( int ref );

Boolean SR_SendCloseRequest ( int ref, SRCloseRequest *crq );
Boolean SR_SendCloseResponse ( int ref, SRCloseResponse *crp );
SRCloseRequest *SR_ReadCloseRequest ( int ref );
SRCloseResponse *SR_ReadCloseResponse ( int ref );

#endif
