//
// C++ Implementation: $MODULE$
//
// Description:
//
//
// Author: Christian Hubinger <chubinger@gmail.com>, (C) 2003
//
// Copyright: See COPYING file that comes with this distribution
//
//
/***************************************************************************
 *                                                                         *
 *   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 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/


#include "kmfprotocol.h"

// QT includes

// KDE includes
#include <kdebug.h>

// project includes
#include "kmfgenericdoc.h"
#include "kmfnetzone.h"

KMFProtocol::KMFProtocol( QObject* parent ) : NetfilterObject( parent ) {
	m_object_type = NetfilterObject::PROTOCOL;
	m_limit_interval = "minute";
	m_limit = -1;
	m_log = false;
	m_doc = 0;
	m_zone = 0;
	if ( KMFGenericDoc* doc = dynamic_cast<KMFGenericDoc*> ( parent ) ) {
		m_doc = doc;
		m_type = LIBRARY;
	}
	if ( KMFNetZone* zone = dynamic_cast<KMFNetZone*> ( parent ) ) {
		m_zone = zone;
		m_type = USER;
	}
}


KMFProtocol::~KMFProtocol() {
	kdDebug() << "KMFProtocol::~KMFProtocol() " << endl;
	kdDebug() << "Deleting Protocol " << name() << endl;
	m_tcpPorts.clear();
	m_udpPorts.clear();
}

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

void KMFProtocol::addPort( const QString& port, int protocol ) {
	kdDebug() << "void KMFProtocol::addPort( const QString& )" << endl;
	if ( protocol == UDP && m_udpPorts.findIndex( port ) == -1 ) {
		kdDebug() << "KMFProtocol: " << name() << " Register UDP Port:" <<  port << endl;
		m_udpPorts << port;
		changed();
		return;
	} 
	if ( protocol == TCP && m_tcpPorts.findIndex( port ) == -1  ) {
		kdDebug() << "KMFProtocol: " << name() << " Register TCP Port:" <<  port << endl;
		m_tcpPorts << port;
		changed();
		return;
	}
	kdDebug() << "WARNING: ignoring duplicate port entry" << endl;
	
}

void KMFProtocol::delPort( const QString& port, int protocol  ) {
// 	kdDebug() << "void KMFProtocol::delPort( const QString& )" << endl;
	if ( protocol == UDP && m_udpPorts.findIndex( port ) != -1  ) {
		m_udpPorts.remove( m_udpPorts.find( port ) );
		changed();
	} else if ( protocol == TCP && m_tcpPorts.findIndex( port ) != -1 ) {
		m_tcpPorts.remove( m_tcpPorts.find( port ) );
		changed();
	}  else {
		kdDebug() << "WARNING: no entry found to remove" << endl;
	}
}

void KMFProtocol::setLimitInterval( const QString& interval ) {
// 	kdDebug() << "void KMFProtocol::setLimitInterval( const QString& )" << endl;
	m_limit_interval = interval;
	changed();
}

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

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

const QDomDocument& KMFProtocol::getDOMTree() {
// 	kdDebug() << "const QDomDocument& KMFProtocol::getDOMTree()" << endl;
	QDomDocument doc;
	QDomElement root = doc.createElement( "protocol" );
	root.setAttribute( "id", m_object_id );
	root.setAttribute( "name", m_name );
	root.setAttribute( "description", m_desc );
	if ( logging() )
		root.setAttribute( "logging", "yes" );
	else
		root.setAttribute( "logging", "no" );

	if ( io() == INCOMING )
		root.setAttribute( "io", "INCOMMING" );
	if (  io() == OUTGOING )
		root.setAttribute( "io", "OUTGOING" );

	QString lim = "";
	lim = lim.setNum( m_limit );
	lim  += "/" + m_limit_interval;
	root.setAttribute( "limit", lim );

	for ( QStringList::Iterator iterator = m_udpPorts.begin(); iterator != m_udpPorts.end(); ++iterator ) {
		QDomElement port = doc.createElement( "port" );
		root.appendChild( port );
		port.setAttribute("num",*iterator);
		port.setAttribute("protocol","UDP");
	}
	for ( QStringList::Iterator iterator = m_tcpPorts.begin(); iterator != m_tcpPorts.end(); ++iterator ) {
		QDomElement port = doc.createElement( "port" );
		root.appendChild( port );
		port.setAttribute("num",*iterator);
		port.setAttribute("protocol","TCP");
	}

	doc.appendChild( root );
	return *( new QDomDocument( doc ) );
}

void KMFProtocol::loadXML( const QDomDocument& doc ) {
// 	kdDebug() << "void KMFProtocol::loadXML( const QDomDocument& )" << endl;
	QDomElement root = doc.documentElement();
	QDomNode curr = root.firstChild();
	QString name = "";
	QString logging = "";
	QString desc = "";
	QString limit = "";
// 	QString prot = "";
	QString io = "";
	name = root.toElement().attribute( "name" );
	logging = root.toElement().attribute( "logging" );
	desc = root.toElement().attribute( "description" );
	limit = root.toElement().attribute( "limit" );
// 	prot = root.toElement().attribute( "protocol" );
	io = root.toElement().attribute( "io" );
	if ( logging == "yes" ) {
		setLogging(true);
	} else {
		setLogging(false);
	}

	if ( io == "INCOMING")
		m_io = INCOMING;
	if ( io == "OUTGOING" )
		m_io = OUTGOING;
	else
		m_io = OUTGOING;

	setDescription( *( new QString( desc ) ) );
	setName( *(new QString( name ) ) );

	int pos = limit.find('/');
	QString limi = limit.left( pos );
	QString limit_interval = limit.right( limit.length() - pos  -1 );
// 	kdDebug() << "found limit " << limi << " interval " << limit_interval << endl;
	bool ok;
	int lim = limi.toInt( &ok );
	if ( ok )
		m_limit = lim;
	m_limit_interval = limit_interval;

	while ( !curr.isNull() ) {
		if ( curr.isElement() && curr.nodeName() == "port" ) {
			QString port = curr.toElement().attribute( "num" );
			QString protocol = curr.toElement().attribute( "protocol" );
			if ( protocol == "UDP" ) {
				addPort( port, UDP );
			}
			if ( protocol == "TCP" ) {
				addPort( port, TCP );
			}
		}
		curr = curr.nextSibling();
	}
	changed();
// 	kdDebug() << "KMFProtocol - finished parsing XML" << endl;
}
