///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAdmNet.cc
// ----------
// Cego net client interface
//      
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2010-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoAdmNet
// 
// Description: Description: Database administration API 
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// cego includes
#include "CegoAdmNet.h"
#include "CegoDefs.h"

#include <lfcbase/Net.h>

CegoAdmNet::CegoAdmNet()
{
    _pN = 0;
    _pAH = 0;
    _pModule = 0;
}

CegoAdmNet::CegoAdmNet(const Chain& logFile, const Chain& progName, const Chain& logLevel)
{
    _logFile = logFile;
    _progName = progName;
    _logLevel = logLevel;
    _pN = 0;
    _pAH = 0;
    _pModule = 0;
}

CegoAdmNet::~CegoAdmNet()
{
    if ( _pAH )
	delete _pAH;
    if ( _pN ) 
	delete _pN;
    if ( _pModule )
	delete _pModule;
}

void CegoAdmNet::connect(const Chain& serverName, unsigned port, const Chain& user, const Chain& pwd)
{
    Net n (  NETMNG_MSG_BUFLEN, NETMNG_SIZEBUFLEN, NETMNG_MAXSENDLEN );

    _pN = n.connect(serverName, port);

    if ( _logFile.length() > 1 )
    {
	_pModule = new CegoModule(_logFile, _progName);
	
	unsigned modId = 100;
	
	if ( _logLevel == Chain("notice"))
	    _pModule->logModule(modId, "dbdimp", Logger::NOTICE);
	else if ( _logLevel == Chain("error"))
	    _pModule->logModule(modId, "dbdimp", Logger::LOGERR);
	else if ( _logLevel == Chain("debug"))
	    _pModule->logModule(modId, "dbdimp", Logger::DEBUG);
	else
	    _pModule->logModule(modId, "dbdimp", Logger::NONE);
    }
    else
    {
	_pModule = new CegoModule;
    }

    _pAH = new CegoAdminHandler( _pModule, _pN);
    
    CegoAdminHandler::ResultType res = _pAH->requestSession(user, pwd);
    if ( res != CegoAdminHandler::ADM_OK )
    {
	Chain msg;
	_pAH->getMsg(msg);
	throw Exception(EXLOC, msg);
    }
}

void CegoAdmNet::getTableSetInfo(const Chain& tableSet, 
				 ListT<Chain>& tsInfoList, 
				 ListT<Chain>& fileInfoList,
				 ListT<Chain>& logInfoList)
{
    CegoAdminHandler::ResultType res;    
    res = _pAH->reqGetDetailedTSInfo(tableSet);
    handleResult(res);
        
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > tsinfo;
    
    _pAH->getDetailedTableSetInfo(oe, tsinfo);
        
    ListT<CegoFieldValue> *pTSI = tsinfo.First();
    while ( pTSI )
    {
	Chain attr;
	Chain val;

	CegoFieldValue *pF = pTSI->First();
	if ( pF )
	    attr = pF->valAsChain();
	pF = pTSI->Next();
	if ( pF )
	    val = pF->valAsChain();
	
	Chain attrVal = attr + Chain(":") + val;
	tsInfoList.Insert( attrVal );
	pTSI = tsinfo.Next();
    }

    Chain format;
    ListT<ListT<CegoFieldValue> > fileinfo;
    _pAH->getDataFileInfo(oe, fileinfo, format);

    ListT<CegoFieldValue> *pFI = fileinfo.First();
    while ( pFI )
    {
	Chain name;
	Chain type;
	Chain size;
	Chain used;

	CegoFieldValue *pF = pFI->First();
	if ( pF )
	    name = pF->valAsChain();
	pF = pFI->Next();
	if ( pF )
	    type = pF->valAsChain();

	pF = pFI->Next();
	if ( pF )
	    size = pF->valAsChain();

	pF = pFI->Next();
	if ( pF )
	    used = pF->valAsChain();
	
	Chain attrVal = name + Chain(":") + type + Chain(":") + size + Chain(":") + used;
	fileInfoList.Insert( attrVal );

	pFI = fileinfo.Next();
    }

    ListT<ListT<CegoFieldValue> > loginfo;
    _pAH->getLogInfo(oe, loginfo);

    ListT<CegoFieldValue> *pLI = loginfo.First();
    while ( pLI )
    {
	Chain name;
	Chain status;
	Chain size;
	Chain offset;
	Chain usage;

	CegoFieldValue *pF = pLI->First();
	if ( pF )
	    name = pF->valAsChain();
	pF = pLI->Next();
	if ( pF )
	    status = pF->valAsChain();

	pF = pLI->Next();
	if ( pF )
	    size = pF->valAsChain();

	pF = pLI->Next();
	if ( pF )
	    offset= pF->valAsChain();

	pF = pLI->Next();
	if ( pF )
	    usage= pF->valAsChain();
	
	Chain attrVal = name + Chain(":") + status + Chain(":") + size + Chain(":") + offset + Chain(":") + usage;
	logInfoList.Insert( attrVal );

	pLI = loginfo.Next();
    }
}

void CegoAdmNet::getTableSetList(ListT<Chain>& tslist)
{
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqGetTableSetList();
    handleResult(res);
        
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > info;
    
    _pAH->getTableSetList(oe, info);
    
    ListT<CegoFieldValue> *pFL = info.First();
    while ( pFL )
    {
	CegoFieldValue *pF = pFL->First();
	if ( pF )
	    tslist.Insert(pF->valAsChain());
	pFL = info.Next();
    }
}

void CegoAdmNet::startTableSet(const Chain& tableSet, bool doCleanup, bool forceload, bool cpDump, bool noInit)
{
    CegoAdminHandler::ResultType res;
    res = _pAH->reqStartTableSet(tableSet, doCleanup, forceload, cpDump, noInit);
    handleResult(res);    
}

void CegoAdmNet::stopTableSet(const Chain& tableSet)
{
    CegoAdminHandler::ResultType res;    
    res = _pAH->reqStopTableSet(tableSet);
    handleResult(res);   
}

void CegoAdmNet::getThreadInfo(ListT<Chain>& threadInfoList)
{
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqThreadInfo();
    handleResult(res);	

    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > threadinfo;

    _pAH->getThreadInfo(oe, threadinfo);

    ListT<CegoFieldValue> *pTI = threadinfo.First();
    while ( pTI )
    {
	Chain id;
	Chain status;

	CegoFieldValue *pF = pTI->First();
	if ( pF )
	    id = pF->valAsChain();
	pF = pTI->Next();
	if ( pF )
	    status = pF->valAsChain();

	Chain attrVal = id + Chain(":") + status;
	threadInfoList.Insert( attrVal );

	pTI = threadinfo.Next();
    }
}

void CegoAdmNet::getDbThreadInfo(ListT<Chain>& dbThreadInfoList)
{ 
    CegoAdminHandler::ResultType res;

    res = _pAH->reqDbThreadInfo();	
    handleResult(res);
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > dbthreadinfo;
    
    Chain format;
    _pAH->getDbThreadInfo(oe, dbthreadinfo, format);

    ListT<CegoFieldValue> *pDBTI = dbthreadinfo.First();
    while ( pDBTI )
    {
	Chain id;
	Chain numReq;
	Chain status;

	CegoFieldValue *pF = pDBTI->First();
	if ( pF )
	    id = pF->valAsChain();
	pF = pDBTI->Next();
	if ( pF )
	    numReq = pF->valAsChain();
	pF = pDBTI->Next();
	if ( pF )
	    status = pF->valAsChain();

	Chain attrVal = id + Chain(":") + numReq + Chain(":") + status;
	
	dbThreadInfoList.Insert( attrVal );

	pDBTI = dbthreadinfo.Next();
    }
}

void CegoAdmNet::getAdmThreadInfo(ListT<Chain>& admThreadInfoList)
{
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqAdmThreadInfo();
    handleResult(res);
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > admthreadinfo;
    
    Chain format;
    _pAH->getAdmThreadInfo(oe, admthreadinfo, format);

    ListT<CegoFieldValue> *pAdmTI = admthreadinfo.First();
    while ( pAdmTI )
    {
	Chain id;
	Chain numReq;
	Chain status;

	CegoFieldValue *pF = pAdmTI->First();
	if ( pF )
	    id = pF->valAsChain();
	pF = pAdmTI->Next();
	if ( pF )
	    numReq = pF->valAsChain();
	pF = pAdmTI->Next();
	if ( pF )
	    status = pF->valAsChain();

	Chain attrVal = id + Chain(":") + numReq + Chain(":") + status;
	
	admThreadInfoList.Insert( attrVal );

	pAdmTI = admthreadinfo.Next();
    }
}

void CegoAdmNet::importTableSet(const Chain& tableSet, const Chain& impMode, const Chain& impFile)
{
    CegoAdminHandler::ResultType res;
    bool isStructure=false;
    
    res = _pAH->reqImportTableSet(tableSet, isStructure, impFile, impMode);
    handleResult(res);       
}

void CegoAdmNet::exportTableSet(const Chain& tableSet, const Chain& expMode, const Chain& expFile)
{
    CegoAdminHandler::ResultType res;
    bool isStructure=false;
    res = _pAH->reqExportTableSet(tableSet, isStructure, expFile, expMode);
    handleResult(res);        
}
   
void CegoAdmNet::addDataFile(const Chain& tableSet, const Chain& fileType, const Chain& dataFile, unsigned numPages)
{
    CegoAdminHandler::ResultType res;    
    res = _pAH->reqAddDataFile(tableSet, fileType, dataFile, numPages);
    handleResult(res);
}

void CegoAdmNet::defineTableSet(const Chain& tableSet, 
				const Chain& tsRoot,
				unsigned sysSize,
				unsigned tmpSize,
				unsigned appSize,
				unsigned logSize,
				unsigned logNum, 
				unsigned long long orderSize,
				unsigned branchId)
{
    CegoAdminHandler::ResultType res;
    res = _pAH->reqDefineTableSet(tableSet,
				  tsRoot,
				  sysSize,
				  tmpSize,
				  appSize,
				  logSize,
				  logNum, 
				  orderSize,
				  branchId);
    handleResult(res);
}

void CegoAdmNet::createTableSet(const Chain& tableSet)
{
    CegoAdminHandler::ResultType res;   
    res = _pAH->reqCreateTableSet(tableSet);
    handleResult(res);
}

void CegoAdmNet::dropTableSet(const Chain& tableSet) 
{
    CegoAdminHandler::ResultType res;   
    res = _pAH->reqDropTableSet(tableSet);
    handleResult(res);
}

void CegoAdmNet::recoverTableSet(const Chain& tableSet, const Chain& pit, unsigned long long targetlsn)
{
    CegoAdminHandler::ResultType res;
    res = _pAH->reqRecover(tableSet, pit, targetlsn);
    handleResult(res);
}

void CegoAdmNet::handleResult(CegoAdminHandler::ResultType res)
{
    Chain msg;
    _pAH->getMsg(msg);
    
    bool doQuiet=true;

    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	throw Exception(EXLOC, msg);
    }
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {	
	if ( doQuiet == false )
	{
	    Chain msg;
	    
	    _pAH->getMsg(msg);
	    
	    ListT<CegoFieldValue> fvl;
	    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, msg));	    
	}

	res = _pAH->nextInfo();
    }
    
    _pAH->getMsg(msg);
    
    if ( res == CegoAdminHandler::ADM_OK )
    {
	// ok
    }
    else if ( res == CegoAdminHandler::ADM_ERROR )
    {
	throw Exception(EXLOC, msg);
    }
}
   
void CegoAdmNet::disconnect()
{        
    _pAH->closeSession();
}
