//
// C++ Implementation: kmfprotocolusage
//
// Description: 
//
//
// Author: Christian Hubinger <chubinger@irrsinnig.org>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "kmfprotocolusage.h"

// QT includes
#include <tqfile.h>
#include <tqdir.h>
#include <tqdom.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqvaluelist.h>

// KDE includes
#include <kdebug.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kio/netaccess.h>
#include <kio/job.h>
#include <ktrader.h>
#include <klibloader.h>
#include <ktempfile.h>
#include <kfileitem.h>

// project includes
#include "../version.h"
#include "kmfprotocol.h"
#include "kmfprotocollibrary.h"
#include "kmferror.h"
#include "kmferrorhandler.h"
#include "kmfgenericdoc.h"
#include "kmfnetzone.h"
#include "kmfnethost.h"
#include "xmlnames.h"

namespace KMF {

KMFProtocolUsage::KMFProtocolUsage( NetfilterObject* parent, const char* name )  : NetfilterObject( parent, name ) {
	m_protocol = 0;
	m_limit_interval = "minute";
	m_limit = -1;
	m_log = false;
}


KMFProtocolUsage::~KMFProtocolUsage()
{
}

const TQString& KMFProtocolUsage::name() {
//	kdDebug() << "KMFProtocolUsage::name()" << endl;
	if ( ! m_protocol ) {
		kdDebug() << "ERROR: No Protocol Stored in KMFProtocolUsage instance!" << endl;
		return *( new TQString( "ERROR: No Protocol Stored in KMFProtocolUsage instance!") );
	}
	return protocol()->name();
}

const TQString& KMFProtocolUsage::description() {
//	kdDebug() << "KMFProtocolUsage::description()" << endl;
	if ( ! m_protocol ) {
		kdDebug() << "ERROR: No Protocol Stored in KMFProtocolUsage instance!" << endl;
		return *( new TQString( "ERROR: No Protocol Stored in KMFProtocolUsage instance!") );
	}
	return protocol()->description();
}

int KMFProtocolUsage::type() {
	//kdDebug() << "KMFProtocolUsage::type()" << endl;
	return NetfilterObject::PROTOCOLUSAGE;
}
void KMFProtocolUsage::clear() {
	m_limit_interval = "minute";
	m_limit = -1;
	m_log = false;
}

void KMFProtocolUsage::setProtocol( KMFProtocol* p ) {
	// kdDebug() << "KMFProtocolUsage::setProtocol( KMFProtocol* " << p->name() << " )" << endl;
	m_protocol = p;
	
	disconnect( m_protocol, TQT_SIGNAL( destroyed( TQObject* ) ),
		this, TQT_SLOT( slotOnProtocolDeleted( TQObject* ) ) );
	connect( m_protocol, TQT_SIGNAL( destroyed( TQObject* ) ),
		this, TQT_SLOT( slotOnProtocolDeleted( TQObject* ) ) );
}

void KMFProtocolUsage::slotOnProtocolDeleted( TQObject* ) {
	kdDebug() << "KMFProtocolUsage::slotOnProtocolDeleted( TQObject* )" << endl;
	deleteLater();
}


bool KMFProtocolUsage::validUsage() {

	return m_protocol ? true : false;
}

void KMFProtocolUsage::setIO ( int io ) {
	m_io = io;
}

void KMFProtocolUsage::setLimitInterval( const TQString& interval ) {
	// kdDebug() << "void KMFProtocolUsage::setLimitInterval( const TQString& )" << endl;
	if ( m_limit_interval == interval ) {
		return;
	}
	m_limit_interval = interval;
	changed();
}

void KMFProtocolUsage::setLimit( int limit ){
	// kdDebug() << "void KMFProtocolUsage::setLimit( int )" << endl;
	if ( m_limit == limit ) {
		return;
	}
	m_limit = limit;
	changed();
}

void KMFProtocolUsage::setLogging( bool onoff ) {
	// kdDebug() << "void KMFProtocolUsage::setLimit( int )" << endl;
	if ( m_log == onoff ) {
		return;
	}
	m_log = onoff;
	changed();
}

const TQDomDocument& KMFProtocolUsage::getDOMTree() {
	// kdDebug() << "const TQDomDocument& KMFProtocolUsage::getDOMTree()" << endl;
	TQDomDocument doc;
	TQDomElement root = doc.createElement( XML::ProtocolUsage_Element );
	NetfilterObject::saveUuid( root );
	// root.setAttribute( "protocolName", protocol()->name() );
	root.setAttribute( XML::ProtocolUuid_Attribute, protocol()->uuid().toString() );
	
	if ( logging() ) {
		root.setAttribute( XML::Logging_Attribute, XML::Yes_Value );
	} else {
		root.setAttribute( XML::Logging_Attribute, XML::No_Value );
	}
	
	if ( io() == INCOMING ) {
		root.setAttribute( XML::IO_Attribute, XML::Incoming_Value );
	}
	if (  io() == OUTGOING ) {
		root.setAttribute( XML::IO_Attribute, XML::Outgoing_Value );
	}

	TQString lim = "";
	lim = lim.setNum( m_limit );
	lim  += "/" + m_limit_interval;
	root.setAttribute( XML::Limit_Attribute, lim );
	
	doc.appendChild( root );
	return *( new TQDomDocument( doc ) );
}

void KMFProtocolUsage::loadXML( const TQDomDocument& doc, TQStringList& errors ) {
	// kdDebug() << "void KMFProtocolUsage::loadXML( const TQDomDocument& )" << endl;
 	TQDomElement root = doc.documentElement();
 	loadXML( root, errors );
}
void KMFProtocolUsage::loadXML( TQDomNode root, TQStringList& errors ) {
	kdDebug() << "void KMFProtocolUsage::loadXML( TQDomNode root )" << endl;
	NetfilterObject::loadUuid ( root, errors );
	TQString protocolName = "";
	TQString protocolUuid = "";
	TQString logging = "";
	TQString desc = "";
	TQString limit = "";

	TQString io = "";
	// protocolName = "";
	

	if ( root.toElement().hasAttribute( XML::ProtocolUuid_Attribute ) ) {
		protocolUuid = root.toElement().attribute( XML::ProtocolUuid_Attribute );
	} /*else if ( root.toElement().hasAttribute( "protocolName" ) ) {
		protocolName = root.toElement().attribute( "protocolName" );
	} */else if ( root.toElement().hasAttribute(  XML::Name_Attribute ) ) {
		protocolName = root.toElement().attribute(  XML::Name_Attribute );
	} else {
		kdDebug() << "ERROR: NO Protocol name found for Protocol usage!" << endl;
		errors.append( KMFError::getAsString( KMFError::NORMAL, i18n( "No Protocol reference found for ProtocolUsage !" ) ) );
		return;
	}
	
	
	if ( ! protocolUuid.isEmpty() ) {
// 		kdDebug() << "Using Protocol Uuid!" << endl;
		KMFProtocol* prot = KMFProtocolLibrary::instance()->findProtocolByUuid( *( new TQUuid( protocolUuid ) ) );
		if ( ! prot ) {
			errors.append( KMFError::getAsString( KMFError::NORMAL, i18n( "Could not find Protocol: %1 in protocol Library" ).arg( protocolUuid ) ) );
			kdDebug() << "ERROR: Could not find Protocol: " << protocolUuid << " in protocol Library" << endl;
			return;
		}
		setProtocol( prot );
	} else {
	// 	kdDebug() << "Using Protocol Name!" << endl;
		errors.append( KMFError::getAsString( KMFError::WARNING, i18n( "Using Protocol Name! As Reference in Protocol Usage." ) ) );
		
		KMFProtocol* prot = KMFProtocolLibrary::instance()->findProtocolByName( protocolName );
		if ( ! prot ) {
			errors.append( KMFError::getAsString( KMFError::NORMAL, i18n( "Could not find Protocol: %1 in protocol Library" ).arg( protocolName ) ) );
			kdDebug() << "ERROR: Could not find Protocol: " << protocolName << " in protocol Library" << endl;
			return;
		}
		setProtocol( prot );
	}
	
	
	
	if ( root.toElement().hasAttribute(  XML::Logging_Attribute ) ) {
		logging = root.toElement().attribute( XML::Logging_Attribute );
		if ( logging == XML::Yes_Value ) {
			setLogging(true);
		} else {
			setLogging(false);
		}
	}
	if ( root.toElement().hasAttribute( XML::IO_Attribute ) ) {
		io = root.toElement().attribute( XML::IO_Attribute );
	
		if ( io == XML::Incoming_Value) {
			m_io = INCOMING;
		} else {
			m_io = OUTGOING;
		}
	}
	
	if ( root.toElement().hasAttribute( XML::Limit_Attribute ) ) {
		limit = root.toElement().attribute( XML::Limit_Attribute );
		int pos = limit.find('/');
		TQString limi = limit.left( pos );
		TQString limit_interval = limit.right( limit.length() - pos  -1 );
		
		bool ok;
		int lim = limi.toInt( &ok );
		if ( ok ) {
			m_limit = lim;
		}
		m_limit_interval = limit_interval;
	}
	changed();
}

}
