/***************************************************************************
*                                                                         *
*   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.                                   *
*                                                                         *
***************************************************************************/
/*
Author: Christian Hubinger <chubinger@gmail.com>, (C) 2001-2004
*/


#include "kmfinstallerplugin.h"


// QT includes
#include <qfile.h>
#include <qtextstream.h>
#include <qmultilineedit.h>
#include <qiconset.h>


// KDE includes
#include <kinstance.h>
#include <kaction.h>
#include <kstdaction.h>
#include <kfiledialog.h>
#include <klocale.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kmessagebox.h>
#include <ktrader.h>
#include <kstandarddirs.h>
#include <kio/netaccess.h>

// Project includes
#include "../kmfwidgets/kmfmainwindow.h"

#include "../core/kmfconfig.h"
#include "../core/kmfdoc.h"
#include "../core/kmfprotocol.h"
#include "../core/kmfiptdoc.h"
#include "../core/kmfgenericdoc.h"
#include "../core/kmfpluginfactory.h"
#include "../kmfwidgets/kmfprocout.h"

#include "../interfaces/kmfcompilerinterface.h"
#include "../interfaces/kmfiptinstallerinterface.h"

#include "linux/kmfiptinstaller.h"

KMFInstallerPlugin::KMFInstallerPlugin( QObject *parent, const char *name )
	: KMFPlugin( parent, name ) {

	m_docType = -1;
	KMFMainWindow* app = 0;
	app = dynamic_cast<KMFMainWindow*>( parent );
	if ( ! app ) {
		KMessageBox::error( 0, "Oops wrong parent class found for kmfinstallerplugin!!!" );
	}
	m_doc = app->doc();

// 	m_installerPlugin = 0;
	m_execWidget = 0;
	m_actionStopFw = new KAction( i18n( "&Reset IPTables" ), "decrypted",
	                              0, this, SLOT( slotStopFirewall() ), actionCollection(), "reset_iptables" );

	m_actionRunFw = new KAction( i18n( "Run Fir&ewall" ), "encrypted",
	                             0, this, SLOT( slotStartFirewall() ), actionCollection(), "run_firewall" );

	m_actionPreviewScript = new KAction( i18n( "&Preview Script" ), "mime_txt",
	                                     0 , this, SLOT( slotShowScript() ), actionCollection(), "preview_script" );

	m_generateInstallPackage  = new KAction( i18n( "&Generate Linux Installation Package" ), "fileexport",
			0 , this, SLOT( slotGenerateInstallerPackage() ), actionCollection(), "generate_install_package" );
	
	m_actionShowConfig = new KAction( i18n( "Show &All Tables" ), "messagebox_info",
	                                  0 , this, SLOT( slotShowConfig() ), actionCollection(), "show_ipt_config" );

	m_actionShowFilter = new KAction( i18n( "Show &Filter Table" ), "messagebox_info",
	                                  0 , this, SLOT( slotShowFilter() ), actionCollection(), "show_filter" );

	m_actionShowNat = new KAction( i18n( "Show &Nat Table" ), "messagebox_info",
	                               0 , this, SLOT( slotShowNat() ), actionCollection(), "show_nat" );

	m_actionShowMangle = new KAction( i18n( "Show &Mangle Table" ), "messagebox_info",
	                                  0 , this, SLOT( slotShowMangle() ), actionCollection(), "show_mangle" );

	m_actionMenu = new KActionMenu( i18n( "Show IPTables Configuration" ), "messagebox_info", this , "show_menu" );

	m_actionMenu->insert( m_actionShowConfig );
	m_actionMenu->insert( m_actionShowFilter );
	m_actionMenu->insert( m_actionShowNat );
	m_actionMenu->insert( m_actionShowMangle );
	m_actionMenu->setDelayed( false );
	m_actionMenu->setStickyMenu( true );
	actionCollection() ->insert( m_actionMenu );

	m_actionInstallFW = new KAction( i18n( "&Install Firewall" ), "down",
	                                 0 , this, SLOT( slotInstallFW() ), actionCollection(), "install_firewall" );

	m_actionUninstallFW = new KAction( i18n( "&Uninstall Firewall" ), "up",
	                                   0 , this, SLOT( slotUninstallFW() ), actionCollection(), "uninstall_firewall" );
	setXMLFile( "kmfinstallerpluginui.rc" );

	slotEnableActions( false );
	connect( app,SIGNAL( sigEnableActions( bool ) ),
         this, SLOT( slotEnableActions(bool ) ) );

	kdDebug() << "\n\nKMFInstallerPlugin: Finished Initialisation\n\n " << endl;
}

KMFInstallerPlugin::~KMFInstallerPlugin() {}


KMFProcOut* KMFInstallerPlugin::execWidget() {
	if ( m_execWidget )
		return m_execWidget;
	kdDebug() << "Need to create new execWidget." << endl;
	m_execWidget = new KMFProcOut( (KMFMainWindow*) parent(), "KMFProcOut" );
	return m_execWidget;
}


void KMFInstallerPlugin::showScript() {
	kdDebug() << "void KMFInstallerPlugin::showScript()" << endl;
	setOutputWidget( execWidget() );
	execWidget()->setText( doc()->compile() );
	showOutput();
}

void KMFInstallerPlugin::installFW() {
	kdDebug() << "void KMFInstallerPlugin::installFW()" << endl;
	if ( doc() ) {
		KMFIPTInstallerInterface *inst2 = KMFPluginFactory::KMFIPTInstaller(
			KMFConfig::oS(), KMFConfig::backend(), parent() ); 
		if ( ! inst2 )
			return;
		inst2->loadScript( doc()->compile() );
		inst2->cmdInstallFW();
	}

}
void KMFInstallerPlugin::uninstallFW() {
	kdDebug() << "void KMFInstallerPlugin::uninstallFW()" << endl;
	if ( doc() ) {
		KMFIPTInstallerInterface *inst2 = KMFPluginFactory::KMFIPTInstaller(
				KMFConfig::oS(), KMFConfig::backend(), parent() ); 
		if ( ! inst2 )
			return;
		inst2->loadScript( doc()->compile() );
		inst2->cmdUninstallFW();
	}
}


void KMFInstallerPlugin::cmdShowRunningConfig( const QString& para ) {
	KMFIPTInstallerInterface *inst2 = KMFPluginFactory::KMFIPTInstaller(
			KMFConfig::oS(), KMFConfig::backend(), parent() ); 
	if ( ! inst2 )
		return;
	inst2->cmdShowRunningConfig( para );
}

void KMFInstallerPlugin::startFW() {
	kdDebug() << "void KMFInstallerPlugin::startFW()" << endl;
	if ( doc() ) {
		KMFIPTInstallerInterface *inst2 = KMFPluginFactory::KMFIPTInstaller(
				KMFConfig::oS(), KMFConfig::backend(), parent() ); 
		if ( ! inst2 )
			return;
		inst2->loadScript( doc()->compile() );
		inst2->cmdRunFW();
	} 
}

void KMFInstallerPlugin::stopFW() {
	kdDebug() << "void KMFInstallerPlugin::stopFW()" << endl;
	if ( doc() ) {
		KMFIPTInstallerInterface *inst2 = KMFPluginFactory::KMFIPTInstaller(
				KMFConfig::oS(), KMFConfig::backend(), parent() ); 
		if ( ! inst2 )
		return;
		inst2->loadScript( doc()->compile() );
		inst2->cmdStopFW();
	}
}

void KMFInstallerPlugin::generateInstallerPackage() {
	kdDebug() << "void KMFInstallerPlugin::stopFW()" << endl;
	if ( doc() ) {
		KMFIPTInstallerInterface *inst2 = KMFPluginFactory::KMFIPTInstaller(
				KMFConfig::oS(), KMFConfig::backend(), parent() ); 
		if ( ! inst2 )
			return;
		inst2->loadScript( doc()->compile() );
		
		QString msg = i18n( "<qt><p>The generated <b>.tar.gz</b> archive contains an install.sh script file that you need to call after extracting the package. <b>(sh ./install.sh)</b><br>To unintall the package call the script unsing the uninstall parameter. <b>(sh ./install.sh uninstall)</b></p></qt>" );
		QString cap = i18n( "Generate Installation Package" );
		KMessageBox::information( 0, msg, cap, "generate_intsllation_package_howto", 0 );
		
		KURL url = KFileDialog::getSaveURL( ":", "*.tar.gz|Gzipped Tar Archive (*.tar.g)"  );
		if ( url.fileName().isEmpty() )
			return;
		
		int answer = 0;
		
		
		if ( KIO::NetAccess::exists( url, false,0 ) ) {
			answer = KMessageBox::warningYesNo( 0, i18n( "<qt>File <b>%1</b> already exists!</p>"
					"<p><b>Overwrite the existing file?</b></p></qt>" ).arg( url.url() ) );
			if ( answer == KMessageBox::No ) {
					return;
			} 
		}
		
		inst2->generateInstallerPackage( url );
	}
}





// ########## Slots for the Actions ###############
void KMFInstallerPlugin::slotStopFirewall() {
	kdDebug() << "void KMFInstallerPlugin::slotResetFirewall() " << endl;
	stopFW();
}

void KMFInstallerPlugin::slotStartFirewall() {
	kdDebug() << "void KMFInstallerPlugin::slotStartFirewall()" << endl;
	startFW();
}

void KMFInstallerPlugin::slotShowScript() {
	kdDebug() << "void KMFInstallerPlugin::slotShowScript()" << endl;
	showScript();
}

void KMFInstallerPlugin::slotShowConfig() {
	kdDebug() << "void KMFInstallerPlugin::slotShowConfig()" << endl;
	cmdShowRunningConfig( "all" );
}

void KMFInstallerPlugin::slotShowFilter() {
	kdDebug() << "void KMFInstallerPlugin::slotShowFilter()" << endl;
	cmdShowRunningConfig( "filter" );
}

void KMFInstallerPlugin::slotShowNat() {
	kdDebug() << "void KMFInstallerPlugin::slotShowNat()" << endl;
	cmdShowRunningConfig( "nat" );
}

void KMFInstallerPlugin::slotShowMangle() {
	kdDebug() << "void KMFInstallerPlugin::slotShowMangle()" << endl;
	cmdShowRunningConfig( "mangle" );
}

void KMFInstallerPlugin::slotInstallFW() {
	kdDebug() << "void KMFInstallerPlugin::slotInstallFW()" << endl;
	installFW();
}

void KMFInstallerPlugin::slotUninstallFW() {
	kdDebug() << "void KMFInstallerPlugin::slotUninstallFW()" << endl;
	uninstallFW();
}

void KMFInstallerPlugin::slotGenerateInstallerPackage() {
	kdDebug() << "void KMFInstallerPlugin::slotGenerateInstallPackage()" << endl;
	generateInstallerPackage();	
}


void KMFInstallerPlugin::slotEnableActions( bool on ) {
	if ( on ) {
		m_actionStopFw->setEnabled( true );
		m_actionRunFw->setEnabled( true );
		m_actionPreviewScript->setEnabled( true );
		m_actionShowConfig->setEnabled( true );
		m_actionShowFilter->setEnabled( true );
		m_actionShowNat->setEnabled( true );
		m_actionShowMangle->setEnabled( true );
		m_actionMenu->setEnabled( true );
		m_actionInstallFW->setEnabled( true );
		m_actionUninstallFW->setEnabled( true );
		m_generateInstallPackage->setEnabled( true );
	} else {
		m_actionStopFw->setEnabled( false );
		m_actionRunFw->setEnabled( false );
		m_actionPreviewScript->setEnabled( false );
/*		m_actionShowConfig->setEnabled( false );
		m_actionShowFilter->setEnabled( false );
		m_actionShowNat->setEnabled( false );
		m_actionShowMangle->setEnabled( false );
		m_actionMenu->setEnabled( false );*/
		m_actionInstallFW->setEnabled( false );
		m_actionUninstallFW->setEnabled( false );
		m_generateInstallPackage->setEnabled( false );
	}
}


// It's usually safe to leave the factory code alone.. with the
// notable exception of the KAboutData data
#include <kaboutdata.h>
#include <klocale.h>

KInstance* KMFInstallerPluginFactory::s_instance = 0L;
// KAboutData* KMFInstallerPluginFactory::s_about = 0L;

KMFInstallerPluginFactory::KMFInstallerPluginFactory( QObject* parent, const char* name )
		: KLibFactory( parent, name ) {
	s_instance = new KInstance( "KMFInstallerPluginFactory" );
}



QObject* KMFInstallerPluginFactory::createObject( QObject* parent, const char* name,
        const char*, const QStringList & ) {
	QObject * obj = new KMFInstallerPlugin( parent, name );
	emit objectCreated( obj );
	return obj;
}


// KInstance* KMFInstallerPluginFactory::instance() {
// 	if ( !s_instance ) {
// 		s_instance = new KInstance( "KMFInstallerPluginFactory" );
// 	}
// 	return s_instance;
// }

extern "C" {
	void* init_libkmfinstallerplugin() {
		return new KMFInstallerPluginFactory;
	}
}

#include "kmfinstallerplugin.moc"
