/***************************************************************************
*   Copyright (C) 2004 by Christoph Thielecke                             *
*   crissi99@gmx.de                                                       *
*                                                                         *
*   Contains parts of code from klcc project                              *
*   (Peter Simonsson <psn@linux.se>).                                      *
*                                                                         *
*   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.                                   *
*                                                                         *
*   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; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/
//BEGIN #includes
#ifndef __KVPNC_H__
#define __KVPNC_H__

#include <qwidget.h>
#include <qstrlist.h>
#include <qpixmap.h>
#include <qtimer.h>
#include <qfile.h>
#include <qdatetime.h>
#include <qptrlist.h>
#include <qlabel.h>
#include <qtextstream.h>
#include <qpixmap.h>
#include <qpoint.h>
#include <qsize.h>
#include <qpopupmenu.h>
#include <kapp.h>
#include <kmainwindow.h>
#include <kaction.h>
#include <kprocess.h>
#include <kwizard.h>
#include <kapp.h>
#include <kprocess.h>
#include <knotifyclient.h>
#include <knotifydialog.h>
#include <kfeedback.h>
#include <dcopobject.h>
#include "kvpnckicker.h"
#include "preferencesdialog.h"
#include "mainview.h"
#include "vpnaccountdata.h"
#include "networkinterface.h"
#include "kvpncconfig.h"
#include "toolinfo.h"
#include "openvpnmanagementhandler.h"

// ID for statusbar
#define ID_STATUS_MSG 1
#define ID_CONNECTION_MSG 2
#define ID_FLASH_MSG 3
//END #includes

/**
* main class of kvpnc
* @author Christoph Thielecke
*/
class KVpnc : public KMainWindow , DCOPObject
{
	Q_OBJECT
	K_DCOP
public:
	/**
	* Konstruktor
	* @param parent Parent widget
	* @param name Name of the Mainwindow
	*/
	KVpnc( KApplication *parent, QWidget*parent = 0, const char *name = 0 );

	/**
	* Destruktor
	*/
	~KVpnc();
protected:
	/**
	* init the actions
	*/
	void initAction();

	/**
	* init the main view
	*/
	void initView();

	/**
	* init the statusbar
	*/
	void initStatusbar();

	/**
	* init the kicker system tray icon
	*/
	void initDockWindow();

	/**
	* sets the gui status
	* @param status The status that will be set
	*/
	void setGuiStatus( int status );

	/**
	* terminates the connection
	* @param proc the connect process
	*/
	void terminateConnection ( QProcess *proc );
	/**
	* called when quit requested
	*/
	virtual bool queryExit();

	/**
	* return the user id of the certificate
	*	@param Cert certificate from wich should be extracted
	* @param user true if user id, false if issuer id
	*/
	QString getX509CertificateID( QString Cert, bool user );

	void profileAddedOrDeleted();
	bool setVirtualIP();

private:
	// FIXME also declared at kvpncconfig -> made it only in one place
	enum ConnectionStatus {disconnected=0, connecting=1, connected=2};
	enum LogType {info=0, remote=1, error=2, success=3, debug=4};

	KApplication *parent;
	QStringList *env;

	KVpncConfig *GlobalConfig;
	KVpncKicker* KVpncDock; //< kicker menu
	KAction* ConnectAction; //< connect action
	KAction* DisconnectAction; //< disconnect action
	KAction *NewSessionAction;
	KAction *SaveSessionAction;
	KAction *DeleteSessionAction;
	KAction *ImportSessionAction;
	KAction *ImportOpenvpnProfileAction;
	KAction *ExportOpenvpnProfileAction;
	KAction *ImportKvpncSettingsAction;
	KAction *ExportKvpncSettingsAction;
	KAction *ImportCertAction;
	KAction *SelectAction; //< line select action
	KAction *ProfileManagerAction;
	KAction *NewProfileWizardAction;
	KAction *HelpAction;
	KAction *PrefAction;
	KAction *DonateAction;
	KAction *ReportBugAction;
	KAction *SendFeedbackMailAction;
	KAction *PreferencesAction; //< show preferences dialog
	KToggleAction *ToolsInfoAction;
	KToggleAction *LogViewerAction;
	KToggleAction *ShowToolbarAction; //< toggle toolbar on/off
	KToggleAction *ShowStatusbarAction; //< toggle statusbar on/off
	KToggleAction *DebugconsoleAction; //< toggle debug console
	KToggleAction *GenerateOpenvpnKeyAction; //< generate OpenVPN key
	MainView* mw; //< Main gui
	QTimer timer;
	QTimer durationTimer; //< timer for counting connection time
	int connectCounter; //< counter for connecting
	int sec, min, hour;
	int racoon_tunnel_state; // 0 => no tunnel, 1 => first tunnel, 2 => second tunnel
	int prevConnectionState; //< needed for setGuiStatus(), holds previous state before disconnect (connected, connecting)

	bool cancelClicked;
	bool deviceaddrstr2addr;
	bool pingtest;
	bool getUserID;
	bool X509CertificateExtractRunning;
	bool X509CertificateExtractUser;
	bool setVirtualIPSuccess;
	bool AuthRetry;
	bool quitFromKicker;
	bool oldPppdStyle; //< true if old style was found ('mppe require')
	bool pppdHasMppeSupport; //< true if pppd has mppe support
	bool testOldPppdStyle;
	bool shutdownIsCalled;
	bool testPppdReplacedefaultroute;
	bool testPppdRequireMppe128;
	bool pppdHasRequireMppe128Support;
	bool pppdHasReplacedefaultrouteSupport;
	bool stopContinue; //< if something happens that causes to abort now
	bool ciscoVpncRunning; //< true if vpnclient is started and cipsec0 is up

	QString OldDefaultroute;
	QString VpncConnectScript;
	QString VpncDisconnectScript;
	QString tmpPath;
	QString ProcessMsg_connect;
	QString ProcessMsg_disconnect;
	QString deviceaddrstr;
	QString deviceaddr;
	QString tmpInterface;
	QString LocalIP;
	QString VpncGateway;
	QString PptpGateway;
	QString VpncScript;
	QString issuerID; // for id extract
	QString userID;   // for id extract
	QString TunnelInterfaceIP;
	QString TmpDns1;
	QString TmpDns2;
	QString VpncDevice;
	QString CiscoVpncDevice;
	QString PppdDevice;
	QString OpenvpnDevice;
	QString IpsecType; //< openswan, strongswan, freeswan
	QString Pkcs11PIN;

	QProcess *ConnectProcess;
	QProcess *DisconnectProcess;
	QProcess *CiscoVpncProcess;
	QProcess *RacoonProcess;
	QProcess *IpsecProcess;
	QProcess *PingProcess;
	QProcess *RacoonTailProcess;
	QProcess *IpsecTailProcess;
	QProcess *X509CertificateExtractProcess;
	QProcess *PptpProcess;
	QProcess *OpenvpnProcess;
	QProcess *CmdBeforeConnectProcess;
	QProcess *CmdBeforeDisconnectProcess;
	QProcess *CmdAfterConnectProcess;
	QProcess *CmdAfterDisconnectProcess;
	QProcess *RouteProcess;
	QProcess *SetVirtualIPProcess;
	QProcess *ReplaceDefaultRouteProcess;
	QProcess *ConnectionStatusCheckProcess;
	QProcess *TestPppdProcess;
	QProcess *TestCiscoVpncProcess;
	QProcess *IptablesProcess;
	QProcess *KillProcess;
	QProcess *PptpRouteProcess;
	QProcess *ChmodProcess;
	QProcess *pppdUpProcess;
	QProcess *pppdDelDefaultRouteProcess;
	QProcess *L2tpdProcess;
	QProcess *RemoveSetkeyProcess;
	QProcess *BugReportProcess;
	QProcess *DonateProcess;

	int TimeOutProcess; //< for timeout
	int ConnectingProcess; //< for killing process
	QPixmap connectedIcon;
	QPixmap disconnectedIcon;
	QPixmap connectingIcon;
	QPixmap *connectingStatusPixmap;
	QPixmap *disconnectedStatusPixmap;
	QPixmap *connectedStatusPixmap;

	QLabel *statusColorLabel;
	QPopupMenu *QuickConnectMenu;

	OpenvpnManagementHandler *managementhandler ;
	KFeedbackDialog *FeedbackDialog;

public slots:
	/** setup KVpnc */
	void slotSettings();
	/** show / hide toolbar */
	void slotShowToolbar();
	/** show / hide statusbar */
	void slotShowStatusbar();
	/** configure key bindings */
	void slotKeyBindings();
	/** configure toolbars */
	void slotConfigToolbars();

	void slotConfigNotifications();


	/**
	* Slot for status message
	* @param text The text that will be set
	* @param id What type its is
	*/
	void slotStatusMsg( const QString &text, int id = ID_STATUS_MSG );

	void connectClicked();
	void disconnectClicked();
	void saveSessionClicked();
	void newSessionClicked();
	void deleteSessionClicked();
	void sessionToggled( const QString& );
	void helpClicked();
	void toolsInfoClicked();
	void donateClicked();
	void reportBugClicked();
	void saveGuiOptions();
	void showNewProfileWizardClicked();


private slots:

	/**
	 *   called if close clicked
	 * @param e the event which happen
	 */
	void closeEvent( QCloseEvent* e );
	bool queryClose();
	void shutdownCalled();
	void slotCancelClicked();
	void slotConnectTimedOut();
	void slotDurationEvent();
	void readOutputFrom_vpnc();
	void readOutputFrom_ciscovpnc();
	void wroteToStdin_vpncConfig();
	void readFromStdout_disconnect();
	void readFromStderr_disconnect();
	void readFromStdout_racoon();
	void readFromStderr_racoon();
	void readFromStdout_racoon_helper();
	void readFromStderr_racoon_helper();
	void readFromStdout_ipsec();
	void readFromStderr_ipsec();
	void readFromStdout_pptp();
	void readFromStderr_pptp();
	void readFromStdout_l2tpd();
	void readFromStderr_l2tpd();
	void readOutput_openvpn();
	void readFromStdout_tail_racoon();
	void readFromStderr_tail_racoon();
	void readOutputFromTail_ipsec();
	void readFromStdout_ping();
	void readFromStderr_ping();
	void readFromStdout_route();
	void readFromStderr_route();
	void readFromStdout_getX509CertificateID();
	void readFromStderr_getX509CertificateID();
	void readFromStdout_setVirtualIP();
	void readFromStderr_setVirtualIP();
	void readFromStdout_connectionStatusCheck();
	void readFromStderr_connectionStatusCheck();
	void readPppdtestProcessOutput();
	void readCiscoVpncTestProcessOutput();
	void quitCalled();
	void quitCalledKicker();
	void pptpProcessExited();
	void prepareL2tpd(); //< write l2tpd conf etc.
	
	void importProfileClicked(); //< PCF import

	void importKvpncSettingsClicked();
	void exportKvpncSettingsClicked();

	void importOpenvpnProfileClicked(); //< OpenVPN config file import
	void doRacoon();
	void doRoutePptp();
	void addRouteIpsec();
	void delRouteIpsec();
	void doChmodPskFile();
	void doTailRacoonLog();
	void doTailIpsecLog();
	void doIptablesRacoon();
	void doIptablesFreeswan();
	void addRouteRacoon();
	void delRouteRacoon();
	void removeIptablesRacoon();
	void removeIptablesFreeswan();
	void removeSetkey();
	void connectionEnded();
	void doPingTest();
	void pingTestExited();
	void vpncStarted();
	void ipsecStarted();
	void racoonStarted();
	void pppdStarted();
	void openvpnStarted();
	void openSSLEnded();
	void importCertClicked();
	void showProfileManagerClicked();
	void executeCommandBeforeConnect();
	void executeCommandAfterConnect();
	void executeCommandBeforeDisconnect();
	void executeCommandAfterDisconnect();
	void slotConnecting();
	void toggleDebugConsole();
	void addAdditionalNetworkRoutes();
	void removeAdditionalNetworkRoutes();
	void showLogViewer();
	void doQuickConnect(int id);
	void startConnectionStatusCheck();
	void generateOpenvpnKey();
	void preserveNetworkEnvironment(); //< save route and resolv.conf
	void restoreNetworkEnvironment(); //< restore route and resolv.conf
	void exportOpenvpnProfileClicked();
	void addFeatureList( KFeedbackQuestion * question );
	void sendFeedbackMail();
	void feedbackMailSent();
	void start_l2tpd();
	bool checkCiscoVpncStatus();
	void startCiscoVpnc();
	
public:
	void importOpenvpnProfileClicked(QString file); //< OpenVPN config file import
	void importProfileClicked(QString file); //< PCF import

	bool backupResolvConf();
	bool restoreResolvConf();

public:
k_dcop:
	QString getVersion();
	void doConnect();
	void doDisconnect();
	uint getConnectedTime();
	QString getStatus();
	QString getCurrentProfile();
	void setProfile(QString profilename);
	void createNewProfile();
	void createNewProfileWithWizard();
	void deleteCurrentProfile();
	void openPreferences();
	void doImportCert();
	void doImportPcf();
	void doImportPcf(QString file);
	void doImportOpenvpnConfig();
	void doImportOpenvpnConfig(QString file);
	QStringList profiles();
	QStringList toolinfo();
	void doQuit();
	void doGenerateOpenvpnKey();
	void doSendFeedbackMail();
	QStringList getProfileTypes();

};

#endif

