/**********************************************************************
 *
 * comtypes.h -- 
 * Copyright (C) 1999,2004  The New Zealand Digital Library Project
 *
 * A component of the Greenstone digital library software
 * from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *********************************************************************/


#ifndef COMTYPES_H
#define COMTYPES_H

#include "gsdlconf.h"
#include "text_t.h"

#if defined(GSDL_USE_OBJECTSPACE)
#  include <ospace\std\vector>
#  include <ospace\std\list>
#  include <ospace\std\memory> // for pair
#  include <ospace\std\map>
#elif defined(GSDL_USE_STL_H)
#  include <vector.h>
#  include <list.h>
#  include <memory.h> // for pair
#  include <map.h>
#else
#  include <vector>
#  include <list>
#  include <memory> // for pair
#  include <map>
#endif


const text_t OAI_EARLIESTTIMESTAMP_OID = "_earliesttimestamp";
         // https://www.tutorialspoint.com/cplusplus/cpp_constants_literals.htm

enum comerror_t {noError, authenticationFailure, protocolError, 
		 configurationError, systemProblem, syntaxError};
text_t get_comerror_string (comerror_t err);


// ShortColInfo ::= SEQUENCE {
//   name GeneralString,
//   host GeneralString,
//   port INTEGER
// }
struct ShortColInfo_t {
  void clear ();
  ShortColInfo_t () {clear();}

  text_t name;
  text_t host;
  int port;
};

// for collection metadata: metadata name -> lang -> value
// for collection macros: macro name -> params -> value
typedef map<text_t, text_tmap, lttext_t> collectionmeta_map; 

#define CCSUniformSearchResultsFormatting 1

#define SIcasefold 1
#define SIstem 2
#define SIaccentfold 4

struct ColInfoResponse_t {
  void clear ();
  ColInfoResponse_t () {clear();} 
  text_t get_collectionmeta(text_t name, text_t lang);
  
  ShortColInfo_t shortInfo;
  bool useBook;	//whether we want to display the book
  bool isPublic;
  bool isBeta;
  bool isSegmented;
  bool isCollectGroup; // used to group a set of collections as one item on the home page
  unsigned long buildDate;
  text_tarray ccsCols;    // empty if collection does not use cross-collection searching
  int ccsOptions; // uses CCS #defines from above
  int stemIndexes; // uses SI #defines from above
  text_tarray languages;
  unsigned long numDocs;     // 0 if not known
  unsigned long numSections; // 0 if not known
  unsigned long numWords;    // 0 if not known
  unsigned long numBytes;    // 0 if not known
  collectionmeta_map  collectionmeta;
  text_tmap      format;
  collectionmeta_map	 collection_macros; // for collectionmacro config directive (> gsdl 2.53)
  text_tmap      building;
  text_t         httpdomain;      // GRB: could these two http items need removing
  text_t         httpprefix;
  text_t         receptionist;
  text_t         buildType;           // 'mg' or 'mgpp' or 'lucene'
  text_t         infodbType;          // 'gdbm', 'sqlite', etc.
  text_t         authenticate;        // 'document' or 'collection'
  text_t         auth_group;          // 'mygroup' 'yourgroup'
  text_tmap      public_documents;    // the acl to allow access to listed documents
  text_tmap      private_documents;   // the acl to disallow access to listed documents
  text_tmap      dynamic_classifiers;
  text_t		 earliestDatestamp;	  // For OAIserver validation. Time since linux Epoch, expressed as (long) integer value in string form
  // This field stored the builddate value from a collection's index/build.cfg file.
  // This field earliestDatestamp was used when oaiaction.calcEarliestDatestamp() needed to
  // determine the earliest timestamp of the repository, by selecting the earliestDatestamp among
  // all oai collections. Now it's no longer used by OAI, as that resorts to consulting oai-inf.db
  // of each collection, which has a collection's earliest timestamp stored, to work out the
  // earliest timestamp among all collections. But the build.cfg builddate stored in the
  // earliestDatestamp field may still be useful in future for some purpose, so leaving it alone.
  
};


// -- filter options which might be supported for the QueryFilter
// --
// -- onePerQuery StartResults   integer
// -- onePerQuery EndResults     integer
// -- onePerQuery QueryType      enumerated (boolean, ranked)
// -- onePerTerm  Term           string ???
// -- onePerTerm  Casefold       boolean
// -- onePerTerm  Stem           boolean
// -- onePerTerm  Index          enumerated
// -- onePerTerm  Subcollection  enumerated
// --
// -- filter options which might be supported for the BrowseFilter
// --
// -- onePerQuery StartResults   integer
// -- onePerQuery EndResults     integer
// -- onePerQuery ParentNode     string ("" will return the browsing available)
// --
// -- The NullFilter always returns the set it was given, it doesn't have
// -- any options

// InfoFiltersResponse ::= SEQUENCE {
//   filterNames StringSet
// }
struct InfoFiltersResponse_t {
  void clear ();

  text_tset filterNames;
};

// InfoFilterOptionsRequest ::= SEQUENCE {
//   filterName GeneralString
// }
struct InfoFilterOptionsRequest_t {
  void clear ();

  text_t filterName;
};

// FilterOption ::= SEQUENCE {
//   name         GeneralString,
//   type         ENUMERATED {booleant(0), integert(1), enumeratedt(2), stringt(3)},
//   repeatable   ENUMERATED {onePerQuery(0), onePerTerm(1), nPerTerm(2)},
//   defaultValue GeneralString,
//   -- the interpretation of the validValues depends on the type
//   -- for boolean: the first value is the false value, the second is true value
//   -- for integer: the first value is the minimum, the second the maximum
//   -- for enumerated: all values a listed
//   -- for string: this value is ignored
//   validValues  StringSequence
// }
struct FilterOption_t {
  void clear ();
  void check_defaultValue ();
  FilterOption_t () {clear();}

  text_t name;

  enum type_t {booleant=0, integert=1, enumeratedt=2, stringt=3};
  type_t type;

  enum repeatable_t {onePerQuery=0, onePerTerm=1, nPerTerm=2};
  repeatable_t repeatable;

  text_t defaultValue;
  text_tarray validValues;
};

bool operator==(const FilterOption_t &x, const FilterOption_t &y);
bool operator<(const FilterOption_t &x, const FilterOption_t &y);


typedef map<text_t, FilterOption_t, lttext_t> FilterOption_tmap;


// InfoFilterOptionsResponse ::= SEQUENCE {
//   filterOptions SET OF FilterOption
// }
struct InfoFilterOptionsResponse_t {
  void clear ();

  FilterOption_tmap filterOptions;
};


// OptionValue ::= SEQUENCE {
//   name  GeneralString,
//   value GeneralString
// }
struct OptionValue_t {
  void clear ();

  text_t name;
  text_t value;
};

typedef vector<OptionValue_t> OptionValue_tarray;


// -- Terms are presented in the same order that they are requested,
// -- any information relating to the terms is in reference to the
// -- index specified for that term.
//
// FilterRequest ::= SEQUENCE {
//   filterName          [0] GeneralString,
//   filterOptions       [1] IMPLICIT SEQUENCE OF OptionValue,
//   docSet              [2] IMPLICIT StringSequence, -- the OID "" represents everything
//   filterResultOptions [3] IMPLICIT BIT STRING {termFreq(0), matchTerms(1), OID(2), 
//                                                subCol(3), ranking(4), docFreq(5), 
//                                                metadata(6)}
// 
//   -- the next set of options are for the metadata request, 
//   -- they can be left blank if metadata is not wanted
//   requestParams       [4] IMPLICIT GeneralString, -- used to negotiate the metadata content
//   refParams           [5] IMPLICIT GeneralString, -- used to decide whether to return a 
//                                                   -- reference to the data or the actual data
//   fields              [6] IMPLICIT StringSet
//   getParents          [7] IMPLICIT BOOLEAN        -- gets metadata of all parents too
// }
#define FRtermFreq   1
#define FRmatchTerms 2
#define FROID        4
#define FRsubCol     8
#define FRranking    16
#define FRdocFreq    32
#define FRmetadata   64
// used to indicate a full text browse query for mgpp
#define FRfullTextBrowse  128
#define FROAI  256

struct FilterRequest_t {
  void clear ();
  FilterRequest_t () {clear();}

  text_t filterName;
  text_t filterLang; // non empty if we want info to be retrived in language specific
  OptionValue_tarray filterOptions;
  text_tarray docSet;        // empty if not used
  int filterResultOptions; // use the FR* defines above

  text_t requestParams; // empty if not used
  text_t refParams;     // empty if not used
  text_tset fields;   // empty if not used
  bool getParents;      // defaults to false
};


// TermInfo ::= SEQUENCE {
//   term       [0] GeneralString,
//   freq       [1] IMPLICIT INTEGER,       -- 0 if not requested
//   matchTerms [2] IMPLICIT StringSequence -- empty if not requested
// }
struct TermInfo_t {
  void clear ();
  TermInfo_t () {clear();}

  text_t term;
  int freq; // 0 if not requested
  text_tarray matchTerms; // empty if not requested
};

typedef vector<TermInfo_t> TermInfo_tarray;


// MetadataInfo ::= SEQUENCE {
//   params  [0] IMPLICIT GeneralString,
//   isRef   [1] IMPLICIT BOOLEAN,
//   values  [3] IMPLICIT SEQUENCE OF GeneralString,
//   name    [4] IMPLICIT GeneralString
// }
struct MetadataInfo_t {
  text_t params;
  bool isRef;
  text_tarray values;
  MetadataInfo_t *parent;

  void clear ();
  MetadataInfo_t ();
  MetadataInfo_t (const MetadataInfo_t &x); // copy constructor
  ~MetadataInfo_t ();
  MetadataInfo_t &operator=(const MetadataInfo_t &x);
};

typedef map<text_t, MetadataInfo_t, lttext_t> MetadataInfo_tmap;

// ResultDocInfo ::= SEQUENCE {
//   OID      [0] IMPLICIT GeneralString,
//   ranking  [1] IMPLICIT INTEGER,             -- 0 if not requested, range 0-10000
//   docFreq  [2] IMPLICIT SEQUENCE OF INTEGER, -- empty if not requested
//   metadata [3] IMPLICIT SEQUENCE OF MetadataInfo, -- no longer a SEQUENCE (SET maybe??)
//   classifier_metadata_type   [4] IMPLICIT GeneralString,       -- empty if not requested
//   classifier_metadata_offset [5] IMPLICIT INTEGER,             -- 0 if not requested
// }
struct ResultDocInfo_t {
  void clear ();
  ResultDocInfo_t () {clear();}

  text_t OID;
  int result_num;          // place in results list
  int ranking;             // 0 if not requested (real ranking*10000)
  int num_terms_matched;   // not available on all versions of mg
  int num_phrase_match;    // not available on all versions of mg
  vector<int> docFreq;           // empty if not requested
  MetadataInfo_tmap metadata;    // empty if not requested
  text_t classifier_metadata_type;        // empty if not requested
  int    classifier_metadata_offset;      // 0 if not requested
  ResultDocInfo_t &operator=(const ResultDocInfo_t &x);
};

typedef vector<ResultDocInfo_t> ResultDocInfo_tarray;


// FilterResponse ::= SEQUENCE {
//   numDocs   [0] IMPLICIT INTEGER,
//   isApprox  [1] ENUMERATED {Exact(0), Approximate(1), MoreThan(2)}, -- whether numDocs is approximate
//   termInfo  [2] IMPLICIT SEQUENCE OF TermInfo,                      -- empty if not required
//   docInfo   [3] IMPLICIT SEQUENCE OF ResultDocInfo                  -- empty if not required
// }

enum isapprox {Exact=0, Approximate=1, MoreThan=2};

struct FilterResponse_t {
  void clear ();
  FilterResponse_t () {clear();}

  text_t error_message;  // Currently only used by Lucene
  int numDocs;
  isapprox isApprox;
  TermInfo_tarray termInfo; // empty if not requested
  ResultDocInfo_tarray docInfo; // empty if not requested
  text_tset stopwords;

  FilterResponse_t &operator=(const FilterResponse_t &x);
};


// DocumentRequest ::= SEQUENCE {
//   OID       GeneralString,
//   docType   GeneralString,
//   docFormat GeneralString
// }
struct DocumentRequest_t {
  void clear ();
  DocumentRequest_t () {clear();}

  text_t OID;
  text_t docType;
  text_t docFormat;
};


// DocumentResponse ::= SEQUENCE {
//   doc OCTET STRING
// }

struct DocumentResponse_t {
  void clear ();
  DocumentResponse_t () {clear();}

  text_t doc;
};


#endif

