#ifndef _CEGOLOGMANAGER_H_INCLUDED_
#define _CEGOLOGMANAGER_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoLogManager.h
// ----------------
// Cego database log manager class definition
//                                                         
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2019 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoLogManager
// 
// Description: Cego database log management
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// LFC INCLUDES
#include <lfcbase/Chain.h>
#include <lfcbase/File.h>

// CEGO INCLUDES
#include "CegoFileHandler.h"
#include "CegoLogHandler.h"
#include "CegoLogRecord.h"
#include "CegoXMLSpace.h"
#include "CegoDefs.h"

class CegoLogManager : public CegoFileHandler, public CegoXMLSpace {
    
public:
    
    enum LogResult { LOG_SUCCESS, LOG_FULL, LOG_ERROR };

    CegoLogManager(const Chain& xmlDef, const Chain& logFile, const Chain& progName);
    ~CegoLogManager();
    
    void initLog(int tabSetId, int size);
    void stopLog(int tabSetId);
    void startLog(int tabSetId);
    int getLogOffset(int tabSetId);
    void resetLog(int tabSetId);
    
    LogResult logAction(int tabSetId, CegoLogRecord& logRec, bool flushLog = true);
    
    void allocateLogConnection(int tabSetId, const Chain& tableSet, const Chain& logHost, int logPort, const Chain& logUser, const Chain& logPwd);
    bool hasLogConnection(int tabSetId);
    void releaseLogConnection(int tabSetId);
    void setLogFile(int tabSetId, const Chain& logFile, bool readOnly);

    unsigned long long getMinLSN(int tabSetId);
    unsigned long long getMaxLSN(int tabSetId);

    void seekToStart(int tabSetId);
    bool logSeek(int tabSetId, unsigned long long lsn);
    bool logRead(int tabSetId, CegoLogRecord& logRec);

    unsigned long long nextLSN(int tabSetId);
    void setCurrentLSN(int tabSetId, unsigned long long lsn);
    unsigned long long getCurrentLSN(int tabSetId);

    Chain getArchiveLogName(const Chain& tableSet, unsigned long long lsn);

    bool switchLogFile(int tabSetId);
    void setActiveLogFile(const Chain& tableSet);
    
private:
    
    int getLFID();
    void switchLFID();
    
    File *_pLog[TABMNG_MAXTABSET];
    File *_pLFID[TABMNG_MAXTABSET];

    Chain _logFile[TABMNG_MAXTABSET];
    int _logSize[TABMNG_MAXTABSET];
    int _logOffset[TABMNG_MAXTABSET];

    char* _logBuf[TABMNG_MAXTABSET];
    int _logBufLen[TABMNG_MAXTABSET];
    
    int _numGroup[TABMNG_MAXTABSET];
	
    unsigned long long _lsn[TABMNG_MAXTABSET];
    int _logPos[TABMNG_MAXTABSET];

    bool _logActive[TABMNG_MAXTABSET];
    
    CegoLogHandler* _pLogHandler[TABMNG_MAXTABSET];
    NetHandler* _pNetHandler[TABMNG_MAXTABSET];

    unsigned long _modId;
};

#endif
