#ifndef _CEGOXMLSPACE_H_INCLUDED_
#define _CEGOXMLSPACE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoXMLSpace.h
// -----------------
// Cego XML space management
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2010 Bjoern Lemke
//
// 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, 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; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// INTERFACE MODULE
//
// Class: CegoXMLSpace 
// 
// Description: global system space data elements
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

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

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

// cego includes
#include "CegoDefs.h"

class CegoXMLSpace {
    
public:

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

    CegoXMLSpace(const Chain& xmlDef);
    ~CegoXMLSpace();

    Element* getDbSpec();

    Element* getTableSetInfo(const Chain& tableSet);
    void setTableSetInfo(const Chain& tableSet, Element *pTS);

    Element* getTableSetList();
    Element* getNodeList();

    void getTableSetList(ListT<Chain>& tsList);

    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);

    int getNumRBRecordSema();
    int getNumRecordSema();
    int getNumSysRecordSema();
    int getNumSysPageSema();
    int getNumDataPageSema();
    int getNumIndexPageSema();
    int getNumRBPageSema();
    int getNumDataFileSema();
    int getNumBufferPoolSema();
    int getMaxFixTries();

    int getPageLockTimeout();
    int getRecLockTimeout();
    int getFileLockTimeout();
    int getPoolLockTimeout();
    int getNumLockTries();

    bool isCaseSensitiveMode();
    bool isQuoteEscapeMode();

    Chain getDateFormatString();

    void setArchRestoreProg(const Chain& progname);
    Chain getArchRestoreProg();

    void setArchRestoreTimeout(int timeout);
    int getArchRestoreTimeout();


    void setUserPwd(const Chain& user, const Chain& password);

    bool isArchiveMode(int tabSetId);
    bool isArchiveMode(const Chain& tableSet);

    void enableArchLog(const Chain& tableSet);
    void disableArchLog(const Chain& tableSet);

    // bool fileRecoveryRequired(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);
    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();
    
    Chain getPrimary(const int tabSetId);
    Chain getPrimary(const Chain& tabSetName);
    Chain getSecondary(const int tabSetId);
    Chain getSecondary(const Chain& tabSetName);
    Chain getMediator(const int tabSetId);
    Chain getMediator(const Chain& tabSetName);

    void setPrimary(const Chain& tabSetName, const Chain& hostName);
    void setSecondary(const Chain& tabSetName, const Chain& hostName);
    void setMediator(const Chain& tabSetName, const Chain& hostName);

    void getMedList(const Chain& hostname, ListT<Chain>& medList);
    void getTSforMedAndPrim(const Chain& mediator, const Chain& primary, ListT<Chain>& tsList);

    int getTabSetId(const Chain& tabSetName);
    Chain getTabSetName(int tabSetId);
    int getTmpFid(const Chain& tabSetName);

    void setTSSysSize(const Chain& tabSetName, int sysSize);
    int getSysSize(const Chain& tabSetName);

    void setTSTmpSize(const Chain& tabSetName, int tmpSize);
    int getTmpSize(const Chain& tabSetName);

    void setTSLogNum(const Chain& tabSetName, int logNum);
    void setTSLogSize(const Chain& tabSetName, int logSize);

    void addTableSetDef(const Chain& tabSetName,
			const Chain& tsRoot,
			const Chain& buTicket,
			const Chain& primary,
			const Chain& secondary,
			const Chain& mediator,
			int sysFileId, int tempFileId, int sysFileSize, int tmpFileSize,
			int logFileSize, int logFileNum, long sortAreaSize);

    void rmTableSetDef(const Chain& tabSetName);

    void setDBHost(const Chain& dbHost);
    void getDBHost(Chain& dbHost);
    void getDataPort(int& dataPort);
    void getAdminPort(int& adminPort);
    void getLogPort(int& logPort);
    void getPidFile(Chain& pidFile);
    int getPageSize();
    
    void setXmlDef(const Chain& xmlDef);

    void initXml(const Chain& dbName, int pageSize, const Chain& hostName, int dbPort, int admPort, int logPort, const Chain& pidFile, const Chain& logMode);
    void xml2Doc();
    void doc2Xml();
    void initDoc();
    
    void setTSRoot(const Chain& tableSet, const Chain& tsRoot);
    Chain getTSRoot(const Chain& tableSet);    

    Chain getDbName();    

    void setTSTicket(const Chain& tableSet, const Chain& tsTicket);
    Chain getTSTicket(const Chain& tableSet);

    int getTID(const Chain& tableSet);

    bool tableSetExists(const Chain& tableSet);

    void setTSSortAreaSize(const Chain& tabSetName, int sortAreaSize);
    long getSortAreaSize(int tabSetId);

    int nextTID(int tabSetId);
    int nextFID();
    int nextTSID();

    void getAllActiveTableSet(ListT<Chain>& tsList);
    void getActiveTableSet(const Chain& primary, ListT<Chain>& tsList, bool includeRecovery = true);

    Chain getTableSetRunState(const Chain& tableSet);
    void setTableSetRunState(const Chain& tableSet, const Chain& status);

    Chain getTableSetSyncState(const Chain& tableSet);
    void setTableSetSyncState(const Chain& tableSet, const Chain& status);
    
    void setCommittedLSN(int tabSetId, long lsn);
    void setCommittedLSN(const Chain& tableSet, long lsn);
    long getCommittedLSN(const Chain& tableSet);

    void getArchLogInfo(int tabSetId, ListT<Chain>& archIdList, ListT<Chain>& archPathList);
    void getArchLogInfo(const Chain& tableSet, ListT<Chain>& archIdList, ListT<Chain>& archPathList);
    void getOccupiedLogList(int tabSetId, ListT<Chain>& occupiedLogList);
    void setLogFileStatus(int 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, int fileId, const Chain& fileName, int fileSize);

    void getLogFileInfo(const Chain& tableSet, ListT<Chain>& lfList, ListT<int>& sizeList, ListT<Chain>& statusList);
    void setLogFileStatus(const Chain& tableSet, const Chain& logFile, const Chain& status);

    void getDataFileInfo(const Chain& tableSet, const Chain& type, ListT<Chain>& dfList, ListT<int>& fidList, ListT<int>& sizeList );

    void getXMLLockStat(Chain& lockName, long& lockCount, long &numRdLock, long &numWrLock, long &sumRdDelay, long &sumWrDelay);

    void addCounter(int tabSetId, const Chain& counterName, long initValue, bool forceSet = false);

    long getCounterValue(int tabSetId, const Chain& counterName, long incValue = 0);
    void setCounterValue(int tabSetId, const Chain& counterName, long value);

    void removeCounter(int tabSetId, const Chain& counterName);
    void getCounterList(int tabSetId, ListT<Chain>& counterNameList);

    void setCheckpointInterval(const Chain& tableSet, int timeout);
    int getCheckpointInterval(const Chain& tableSet);

    void setTSInitFile(const Chain& tableSet, const Chain& initFile);
    Chain getTSInitFile(const Chain& tableSet);


    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);

private:

    void P();
    void V();

    // Chain getRoleAbbrev(const Chain& roleString);
    Element* getTableSetElement(const Chain& tableSet);
    Element* getCachedTableSetElement(int tabSetId);

    bool fitsPerm(const Chain& perm, AccessMode req);
    
    Document *_pDoc;    
    Chain _xmlDef;

    Element* _tsCache[TABMNG_MAXTABSET];
};

#endif

