///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoLogHandler.cc
// -----------------
// Cego log handler 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: CegoLogHandler
// 
// Description: 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

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

// cego includes
#include "CegoLogHandler.h"
#include "CegoXMLdef.h"

CegoLogHandler::CegoLogHandler( CegoModule *pModule, NetHandler *pN)
{
    _pN = pN;
    _pModule = pModule;
    
    Document *pDoc = new Document(XML_CEGO);
    pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
    
    _xml.setDocument(pDoc);

    _modId = _pModule->getModId("CegoLogHandler");
}

CegoLogHandler::~CegoLogHandler()
{
    Document *pDoc = _xml.getDocument();
    pDoc->clear();
    delete pDoc;
}

void CegoLogHandler::requestLogSession(const Chain& tableSet)
{
    _pModule->log(_modId, Logger::DEBUG, Chain("Request log session ..."));
    _xml.getDocument()->clear();
    
    Element* pRoot = new Element(XML_FRAME_ELEMENT);
    _xml.getDocument()->setRootElement(pRoot);
    _xml.getDocument()->setDocType(Chain(XML_LOGSESSION_REQUEST));
    _xml.getDocument()->setAttribute(XML_TABLESET_ATTR, tableSet);

    Chain request;
    _xml.getXMLChain(request);
    _pN->setMsg(request, request.length());
    _pN->writeMsg();    
    _pN->recvAck();
}

bool CegoLogHandler::acceptLogSession(Chain& tableSet)
{
	    
    _pModule->log(_modId, Logger::DEBUG, Chain("Accepting session"));
            
    try {

	_xml.getDocument()->clear();
	_xml.setChain( _pN->getMsg() );	
	_xml.parse();
	       
	Chain docType = _xml.getDocument()->getDocType();

	if ( docType != Chain(XML_LOGSESSION_REQUEST) )
	{
	    _pN->sendNack();
	    return false;
	}
	else
	{
	    tableSet = _xml.getDocument()->getAttributeValue(XML_TABLESET_ATTR);
	    _pN->sendAck();
	    return true;
	}	
    }
    catch ( Exception e)
    {
	
	Chain msg;
	e.pop(msg);
	
	_pModule->log(_modId, Logger::LOGERR, Chain("Aborting session. Reason=") + msg);
	
	_pN->sendNack();
	return false;
	
    }
}

void CegoLogHandler::setNetHandle(NetHandler *pN)
{
    _pN = pN;
}

void CegoLogHandler::getMsg(Chain& msg)
{
    Element *pRoot = _xml.getDocument()->getRootElement();
    
    if ( pRoot )
    {	
	msg = pRoot->getAttributeValue(XML_MSG_ATTR);
    }
}

void CegoLogHandler::getTableSet(Chain& tableSet)
{
    Element *pRoot = _xml.getDocument()->getRootElement();
    
    if ( pRoot )
    {	
	tableSet = pRoot->getAttributeValue(XML_TABLESET_ATTR);
    }
}

bool CegoLogHandler::sendLogEntry(char* logBuf, int len)
{

    try 
    {
	_pN->setMsg(logBuf, len);
	_pN->writeMsg();
	return _pN->recvAck();
    }
    catch ( Exception e ) 
    {
	Chain msg;
	e.pop(msg);
	_pModule->log(_modId, Logger::LOGERR, msg);
	return false;
    }
}

void CegoLogHandler::closeSession()
{
    char termSession = 0;
    _pN->setMsg(&termSession, 1);
    _pN->writeMsg();
}

bool CegoLogHandler::receiveLogEntry(char* &logBuf, int &len)
{

    try 
    {
	_pN->readMsg();
    }
    catch ( Exception e )
    {
	Chain msg;
	e.pop(msg);
	_pModule->log(_modId, Logger::LOGERR, msg);
	return false;
    } 
    
    if ( _pN->getMsgSize() == 1 )
    {
	return false;
    }
    else
    {	
	logBuf = _pN->getMsg();
	len = _pN->getMsgSize();
	return true;
    }
}

void CegoLogHandler::sendAck()
{
    _pN->sendAck();
}

void CegoLogHandler::sendNack()
{
    _pN->sendNack();
}
