///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoMediatorThread.cc  
// ---------------------                                                     
// Cego mediator thread class implementation
//                                                         
// 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.
//
// IMPLEMENTATION MODULE
//
// Class: CegoMediatorThread
// 
// Description: 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfc/Exception.h>
#include <lfc/Net.h>
#include <lfc/Sleeper.h>

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

CegoMediatorThread::CegoMediatorThread(CegoDatabaseManager *pDBMng) : Thread()
{
    _pDBMng = pDBMng;
    _terminated = false;
    _modId = _pDBMng->getModId("CegoMediatorThread");
}

CegoMediatorThread::~CegoMediatorThread()  
{
    _terminated=true;
    _joined=false;
    int count=0;
    while ( _joined == false && count < 10 )
    {
	Sleeper s;
	s.secSleep(1);
	count++;
    }
    
    if ( _joined )
    {
	_pDBMng->log(_modId, Logger::NOTICE, Chain("Mediator thread terminated"));
	join(getTid());
    }
    else
    {
	_pDBMng->log(_modId, Logger::NOTICE, Chain("Canceling hanging mediator thread ..."));
	cancel();
    }
}

void CegoMediatorThread::getDbSpec(const Chain& dbSpecFileName, const Chain& medHost, int medPort, const Chain& user, const Chain& passwd)
{

    Net n ( NETMNG_MSG_BUFLEN, NETMNG_SIZEBUFLEN );
    
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Connecting to ") + medHost + Chain(":") + Chain(medPort) + Chain(" ..."));

    NetHandler *pN = n.connect(medHost, medPort);

    CegoAdminHandler *pAH = new CegoAdminHandler(_pDBMng, pN);

    
    CegoAdminHandler::ResultType res;
    res  = pAH->requestSession(user, passwd, false);
    
    if ( res == CegoAdminHandler::ADM_OK )
    {
	Chain msg;
	pAH->getMsg(msg);	    
	_pDBMng->log(_modId, Logger::NOTICE,  msg);
    }
    else if ( res == CegoAdminHandler::ADM_ERROR )
    {
	
	Chain msg;
	pAH->getMsg(msg);

	delete pAH;
	delete pN;

	throw Exception(EXLOC, msg);
    }
	    
    
    Chain dbSpec;
    res = pAH->reqGetDbSpec(dbSpec);
    
    if ( res == CegoAdminHandler::ADM_OK )
    {
	Chain msg;
	pAH->getMsg(msg);
	
	_pDBMng->log(_modId, Logger::NOTICE,  msg);
	
	
	File dbSpecFile(dbSpecFileName);
	
	dbSpecFile.open(File::WRITE);
	dbSpecFile.writeChain(dbSpec);
	dbSpecFile.close();
	
    }
    else if ( res == CegoAdminHandler::ADM_ERROR )
    {
	
	Chain msg;
	pAH->getMsg(msg);

	pAH->closeSession();
	delete pAH;
	delete pN;

	throw Exception(EXLOC, msg);
       
    } 

    pAH->closeSession();
    
    delete pAH;
    delete pN;

}

void* CegoMediatorThread::job(void* arg)
{

    while ( _terminated == false )
    {
	try
	{
	    _pDBMng->cleanSession(NETMNG_DBHANDLE_TTL);
	    
	    Sleeper s;
	    s.secSleep(NETMNG_DBHANDLE_CHK);
	    
	}
	catch ( Exception e)
	{
	    e.print();
	}
	
    }

    _joined = true;

    return 0;
}

    
