#ifndef _CEGOXMLSPACE_H_INCLUDED_
#define _CEGOXMLSPACE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoXMLSpace.h
// -----------------
// Cego XML space management
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoXMLSpace 
// 
// Description: XML based database control file management
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfcbase/ListT.h>
#include <lfcbase/SetT.h>
#include <lfcbase/Chain.h>
#include <lfcbase/Logger.h>
#include <lfcbase/BigDecimal.h>


// xml includes
#include <lfcxml/Document.h>

// cego includes
#include "CegoDefs.h"
#include "CegoFileHandler.h"
#include "CegoAdminHandler.h"

class CegoXMLSpace : public CegoFileHandler {
    
public:

    enum AccessMode { READ, WRITE, MODIFY, EXEC, ALL };

    CegoXMLSpace(const Chain& xmlDef, const Chain& logFile, const Chain& progName);
    ~CegoXMLSpace();

    Element* getDbSpec();
    Element* getTableSetInfo(const Chain& tableSet);
    void setTableSetInfo(const Chain& tableSet, Element *pTS);
    Element* getTableSetList();
    Element* getNodeList();
    void getTableSetList(ListT<Chain>& tsList);
    Chain getDbName();
    unsigned getPageSize();
    void addHost(const Chain& hostName, const Chain& status);
    void setHostStatus(const Chain& hostName, const Chain& status);
    void getStatusByHost(const Chain& hostName, Chain& status);
    void removeHost(const Chain& hostName);
    unsigned getSelectTimeout();
    unsigned getQueueDelay();
    unsigned getNumRBRecordSema();
    unsigned getNumRecordSema();
    unsigned getNumSysRecordSema();
    unsigned getNumSysPageSema();
    unsigned getNumDataPageSema();
    unsigned getNumIndexPageSema();
    unsigned getNumRBPageSema();
    unsigned getNumDataFileSema();
    unsigned getNumBufferPoolSema();
    unsigned getMaxFixTries();
    unsigned getMaxPageDelete();
    unsigned getPageLockTimeout();
    unsigned getRecLockTimeout();
    unsigned getFileLockTimeout();
    unsigned getPoolLockTimeout();
    unsigned getNumLockTries();
    void setNumQueryLast(const unsigned numLast);
    unsigned getNumQueryLast();
    void setNumQueryCost(const unsigned numCost);
    unsigned getNumQueryCost();
    unsigned getMaxSendLen();
    void adjustPageOffset();
    PageIdType getNextPageOffset(unsigned numPages);
    void setSysPageOffset(const unsigned tabSetId, const PageIdType pageOffset);
    PageIdType getSysPageOffset(const unsigned tabSetId);
    void setTempPageOffset(const unsigned tabSetId, const PageIdType pageOffset);
    PageIdType getTempPageOffset(const unsigned tabSetId);
    bool allowDuplicateNull();
    char getCaseSensitiveFlag();
    void setQuoteEscapeMode(bool m);
    bool isQuoteEscapeMode();
    Chain getDateTimeFormat();
    BigDecimal::RoundMode getRoundMode();
    
    ListT<Chain> getDateFormatList();
    void setArchRestoreProg(const Chain& progname);
    Chain getArchRestoreProg();
    void setArchRestoreTimeout(unsigned timeout);
    unsigned getArchRestoreTimeout();
    void setBackupProg(const Chain& progname);
    Chain getBackupProg();
    void setUserPwd(const Chain& user, const Chain& password);
    Chain getUserPwd(const Chain& user);
    bool isArchiveMode(unsigned tabSetId);
    bool isArchiveMode(const Chain& tableSet);
    void enableArchLog(const Chain& tableSet);
    void disableArchLog(const Chain& tableSet);
    void addUser(const Chain& user, const Chain& password);
    void removeUser(const Chain& user);
    void changePassword(const Chain& user, const Chain& password);    
    void assignUserRole(const Chain& user, const Chain& role);
    void removeUserRole(const Chain& user, const Chain& role);
    void createRole(const Chain& role);
    void dropRole(const Chain& role);
    Element* getPermInfo(const Chain& role);
    void setPerm(const Chain& role, const Chain& permid, const Chain& tableset, const Chain& filter, const Chain& perm);
    void removePerm(const Chain& role, const Chain& permid);
    Chain getUserRole(const Chain& user);
    void setUserTrace(const Chain& user, bool isOn);
    bool checkAdminUser(const Chain& user, const Chain& password, bool& isTrace);
    void getAdminUser(Chain& user, Chain& password);
    bool checkUser(const Chain& user, const Chain& password, Chain& msg, bool& isTrace);
    void incUserQuery(const Chain& user);
    Element* getUserList();
    Element* getRoleList();

    unsigned getTabSetId(const Chain& tabSetName) const;
    Chain getTabSetName(unsigned tabSetId);
    unsigned getTmpFid(const Chain& tabSetName);
    void setTSSysSize(const Chain& tabSetName, unsigned sysSize);
    unsigned getSysSize(const Chain& tabSetName);
    void setTSTmpSize(const Chain& tabSetName, unsigned tmpSize);
    unsigned getTmpSize(const Chain& tabSetName);
    void setTSLogNum(const Chain& tabSetName, unsigned logNum);
    void setTSLogSize(const Chain& tabSetName, unsigned logSize);
    void resetTSRoot(const Chain& tableSet, const Chain& tsRoot);
    void setTSAppSize(const Chain& tabSetName, unsigned appSize);
    void setAppendMode(const Chain& tabSetName, bool isAppend);
    bool getAppendMode(const Chain& tabSetName);
    void setAutoCorrect(const Chain& tabSetName, const Chain& mode);
    Chain getAutoCorrect(const Chain& tabSetName);
    void setTableCacheMode(const Chain& tabSetName, bool isEnabled);
    bool getTableCacheMode(const Chain& tabSetName);
    void setTableCacheFilter(const Chain& tabSetName, const Chain& filter);
    Chain getTableCacheFilter(const Chain& tabSetName);
    void setTableCacheMaxSize(const Chain& tabSetName, unsigned cacheSize);
    unsigned getTableCacheMaxSize(const Chain& tabSetName);
    void setTableCacheMaxEntry(const Chain& tabSetName, unsigned maxEntry);
    unsigned getTableCacheMaxEntry(const Chain& tabSetName);
    void setTableCacheHashRange(const Chain& tabSetName, unsigned hashRange);
    unsigned getTableCacheHashRange(const Chain& tabSetName);
    void setQueryCacheMode(const Chain& tabSetName, bool isEnabled);
    bool getQueryCacheMode(const Chain& tabSetName);
    void setMaxQueryCacheEntry(const Chain& tabSetName, unsigned numEntry);
    unsigned getMaxQueryCacheEntry(const Chain& tabSetName);
    void setMaxQueryCacheSize(const Chain& tabSetName, unsigned cacheSize);
    unsigned getMaxQueryCacheSize(const Chain& tabSetName);
    void setQueryCacheThreshold(const Chain& tabSetName, unsigned threshold);
    unsigned getQueryCacheThreshold(const Chain& tabSetName);
    void setQueryCacheHashRange(const Chain& tabSetName, unsigned hashRange);
    unsigned getQueryCacheHashRange(const Chain& tabSetName);
    void setCheckPointDump(const Chain& tabSetName, bool isEnabled);
    bool checkPointDumpEnabled(unsigned tabSetId);
    void addTableSetDef(const Chain& tabSetName,
			const Chain& tsRoot,
			unsigned sysFileId, unsigned tempFileId, unsigned sysFileSize, unsigned tmpFileSize, unsigned appFileSize,
			unsigned logFileSize, unsigned logFileNum, unsigned long long sortAreaSize, unsigned branchId);
    void rmTableSetDef(const Chain& tabSetName);
    void setDBHost(const Chain& dbHost);
    void getDBHost(Chain& dbHost);
    void getDataPort(unsigned& dataPort);
    void getAdminPort(unsigned& adminPort);
    void getLogPort(unsigned& logPort);
    void setXmlDef(const Chain& xmlDef);
    void initXml(const Chain& dbName, unsigned pageSize, const Chain& hostName, unsigned dbPort, unsigned admPort, unsigned logPort, const Chain& logLevel, const Chain& csmode, bool qescmode);
    void xml2Doc();
    void doc2Xml();
    void initDoc();
    void setTSRoot(const Chain& tableSet, const Chain& tsRoot);
    Chain getTSRoot(const Chain& tableSet) const;    
    void nextTableSetBackupBranch(const Chain& tableSet);
    Chain getTableSetBackupBranch(const Chain& tableSet);
    unsigned long long getTID(const Chain& tableSet);
    bool tableSetExists(const Chain& tableSet);
    void setTSSortAreaSize(const Chain& tabSetName, unsigned long long sortAreaSize);
    unsigned long long getTSSortAreaSize(unsigned tabSetId);
    unsigned long long nextTID(unsigned tabSetId);
    unsigned nextFID();
    unsigned nextTSID();
    void getAllActiveTableSet(ListT<Chain>& tsList);
    void getActiveTableSet(ListT<Chain>& tsList, bool includeRecovery = true, bool includeOffline = false);
    ListT<unsigned> getOnlineTableSet() const;
    Chain getTableSetRunState(unsigned tabSetId);
    void setTableSetRunState(unsigned tabSetId, const Chain& status);
    Chain getTableSetRunState(const Chain& tableSet);
    void setTableSetRunState(const Chain& tableSet, const Chain& status);

    void setCommittedLSN(unsigned tabSetId, unsigned long long lsn);
    void setCommittedLSN(const Chain& tableSet, unsigned long long lsn);
    unsigned long long getCommittedLSN(const Chain& tableSet);
    void getArchLogInfo(unsigned tabSetId, ListT<Chain>& archIdList, ListT<Chain>& archPathList);
    void getArchLogInfo(const Chain& tableSet, ListT<Chain>& archIdList, ListT<Chain>& archPathList);
    void getOccupiedLogList(unsigned tabSetId, ListT<Chain>& occupiedLogList);
    void setLogFileStatus(unsigned tabSetId, const Chain& logFile, const Chain& status);
    bool addArchLog(const Chain& tableSet, const Chain& archId, const Chain& archPath);
    bool removeArchLog(const Chain& tableSet, const Chain& archId);
    void addDataFile(const Chain& tableSet, const Chain& type, unsigned fileId, const Chain& fileName, unsigned fileSize);
    void getLogFileInfo(const Chain& tableSet, ListT<Chain>& lfList, ListT<unsigned>& sizeList, ListT<Chain>& statusList);
    void setLogFileStatus(const Chain& tableSet, const Chain& logFile, const Chain& status);
    void getDataFileInfo(const Chain& tableSet, ListT<Chain>& dfList);
    void getDataFileInfo(const Chain& tableSet, const Chain& type, ListT<Chain>& dfList, ListT<unsigned>& fidList, ListT<unsigned>& sizeList );
    void getXMLLockStat(Chain& lockName, unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay);
    void addCounter(unsigned tabSetId, const Chain& counterName, unsigned long long initValue, bool forceSet = false);
    unsigned long long getCounterValue(unsigned tabSetId, const Chain& counterName, unsigned long long incValue = 0);
    unsigned long long setCounterValue(unsigned tabSetId, const Chain& counterName, unsigned long long value);
    void removeCounter(unsigned tabSetId, const Chain& counterName);
    void getCounterList(unsigned tabSetId, ListT<Chain>& counterNameList);
    void setCheckpointInterval(const Chain& tableSet, unsigned timeout);
    unsigned getCheckpointInterval(const Chain& tableSet);
    void setTSInitFile(const Chain& tableSet, const Chain& initFile);
    Chain getTSInitFile(const Chain& tableSet);
    bool getProcCacheEnabled(unsigned tabSetId);
    void setProcCacheEnabled(unsigned tabSetId, const bool isEnabled);
    void getRoleSet(const Chain& user, SetT<Chain>& roleSet);
    bool matchRole(const Chain& role, const Chain tableSet, const Chain& objPattern, AccessMode perm);
    bool getModuleList(ListT<Chain> &modList);
    Logger::LogLevel getLogLevel(const Chain& module);
    Chain getSysFileName(const Chain& tableSet);
    Chain getTmpFileName(const Chain& tableSet);

    void verifyXMLLock(CegoAdminHandler* pAH);

private:

    void P() const;
    void V() const;
    void getDBHostLocked(Chain& dbHost);
    Element* getTableSetElement(const Chain& tableSet) const;
    Element* getCachedTableSetElement(unsigned tabSetId);
    bool fitsPerm(const Chain& perm, AccessMode req);
 
    Document *_pDoc;    
    Chain _xmlDef;
    Element* _tsCache[TABMNG_MAXTABSET];
    unsigned long _modId;
};
#endif
