/***************************************************************************
*   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 *qparent = 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();

	void saveProperties( KConfig* );
	void readProperties( KConfig* );

public:
	void restore(KConfig *config, int i);
	void restore();

	/**
	* 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 *RenameSessionAction;
	KAction *ImportSessionAction;
	KAction *ImportOpenvpnProfileAction;
	KAction *ExportOpenvpnProfileAction;
	KAction *ImportFreeswanProfileAction;
	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
	KAction *ManageCiscoCertAction; //< show cisco cert manager
	KAction *CiscoCertEnrollmentAction; //< show cisco cert enrollment dialog
	KToggleAction *ToolsInfoAction;
	KToggleAction *VpnTypesInfoAction;
	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
	QTimer IpsecWhackStatusTimer; //< getting ipsec status periodically
	QTimer L2tpWaitForPppUpTimer; //< getting ppp device
	int connectCounter; //< counter for connecting
	int RacoonctlConnectCounter; //<< counter for waiting of adminsock
	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 shutdownIsCalled;
	bool stopContinue; //< if something happens that causes to abort now
	bool ciscoVpncRunning; //< true if vpnclient is started and cipsec0 is up
	bool showProfilesOnly; //< if true only the profiles will shown in preferencesdialog
	bool IpsecStartingInProgress;

	bool IpsecPhase1Up;
	bool IpsecPhase2Up;

	bool IpsecStatusCheck;

	bool pppdHasReplacedefaultrouteSupport;

	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 L2tpPppDevice;
	QString PppdDevice;
	QString OpenvpnDevice;
	QString SshDevice;
	QString IpsecType; //< openswan, strongswan, freeswan
	QString Pkcs11PIN;

	QProcess *VpncProcess;
	KProcess *IpsecConnectProcess;
	QProcess *DisconnectProcess;
	QProcess *CiscoVpncProcess; //< vpnclient
	QProcess *RacoonProcess; //< racoon
	QProcess *RacoonHelperProcess;
	QProcess *IpsecProcess; //< freeswan/openswan/strongswan
	QProcess *IpsecStartProcess;
	QProcess *IpsecWhackProcess; //< ipsec whack --initate
	QProcess *IpsecWhackStatusProcess; //< ipsec whack --status
	QProcess *IpsecWhackListenProcess; //< ipsec whack --listen
	QProcess *IpsecWhackDeleteProcess; //< ipsec whack --delete
	QProcess *PingProcess;
	QProcess *RacoonTailProcess;
	QProcess *RacoonctlProcess; //< racoonctl
	QProcess *X509CertificateExtractProcess;
	QProcess *PptpProcess;
	QProcess *OpenvpnProcess;
	QProcess *CmdBeforeConnectProcess;
	QProcess *CmdBeforeDisconnectProcess;
	QProcess *CmdAfterConnectProcess;
	QProcess *CmdAfterDisconnectProcess;
	QProcess *SetFirewallAfterConnectProcess;
	QProcess *SetFirewallBeforeDisconnectProcess;
	QProcess *RouteProcess;
	QProcess *SetVirtualIPProcess;
	QProcess *ReplaceDefaultRouteProcess;
	QProcess *ConnectionStatusCheckProcess;
	QProcess *TestCiscoVpncProcess;
	QProcess *IptablesProcess;
	QProcess *KillProcess;
	QProcess *PptpRouteProcess;
	QProcess *ChmodProcess;
	QProcess *pppdUpProcess;
	QProcess *pppdDelDefaultRouteProcess;
	QProcess *L2tpdProcess;
	QProcess *OpenL2tpProcess;
	QProcess *RemoveSetkeyProcess;
	QProcess *BugReportProcess;
	QProcess *DonateProcess;
	QProcess *VtundProcess;
	QProcess *StartStopOpenl2tpProcess;
	KProcess *SshProcess;
	QProcess *backupDefaultRouteProcess;
	QProcess *pptpdKillProcess;
	QProcess *SshDownProcess;
	QProcess *pppdDownProcess;
	QProcess *killracoonprocess;
	QProcess *killl2tpdprocess;
	QProcess *SshUpProcess;

	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;

	QString L2tpdBufferStdoutString;
	QString L2tpdBufferStderrString;


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 renameSessionClicked ();
	void sessionToggled( const QString& );
	void helpClicked();
	void toolsInfoClicked();
	void vpnTypesInfoClicked();
	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_ipsecwhack();
	void readFromStderr_ipsecwhack();
	void readFromStdout_ipsecwhacklisten();
	void readFromStderr_ipsecwhacklisten();
	void readFromStdout_ipsecwhackstatus();
	void readFromStderr_ipsecwhackstatus();
	void readFromStdout_ipsecwhackdelete();
	void readFromStderr_ipsecwhackdelete();
	void readFromStdout_pptp();
	void readFromStderr_pptp();
	void readFromStdout_l2tpd();
	void readFromStderr_l2tpd();
	void processStdout_l2tpd();
	void processStderr_l2tpd();
	void readFromStdout_openl2tp();
	void readFromStderr_openl2tp();
	void readFromStdout_startstopOpenl2tp();
	void readFromStderr_startstopOpenl2tp();
	void checkL2tpPppUp();
	void readOutput_openvpn();
	void readFromStdout_vtun();
	void readFromStderr_vtun();
	void readFromStdout_ssh(KProcess *proc, char *buffer, int buflen);
	void readFromStderr_ssh(KProcess *proc, char *buffer, int buflen);
	void readFromStdout_executeCommandBeforeConnect();
	void readFromStderr_executeCommandBeforeConnect();
	void readFromStdout_executeCommandAfterConnect();
	void readFromStderr_executeCommandAfterConnect();
	void readFromStdout_executeCommandBeforeDisconnect();
	void readFromStderr_executeCommandBeforeDisconnect();
	void readFromStdout_executeCommandAfterDisconnect();
	void readFromStderr_executeCommandAfterDisconnect();


	void readFromStdout_tail_racoon();
	void readFromStderr_tail_racoon();
	void readFromStdout_racoonctl();
	void readFromStderr_racoonctl();
	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 readCiscoVpncTestProcessOutput();
	void quitCalled();
	void quitCalledKicker();
	void pptpProcessExited();
	void vtun_exited(); //< vtund has been exited
	void ipsecwhack_exited(); //< ipsec whack has been exited
	void IpsecWhackStatusProcessExited();
	void racoonctlExited();
	void prepareL2tpd(); //< write l2tpd conf etc.
	void start_ipsec_initiate();
	
	void importProfileClicked(); //< PCF import
	void importIpsecProfileClicked ();

	void importKvpncSettingsClicked();
	void exportKvpncSettingsClicked();

	void importOpenvpnProfileClicked(); //< OpenVPN config file import
	void doRacoon();
	void stopRacoon();
	void doRoutePptp();
	void addRouteIpsec();
	void delRouteIpsec();
	void doTailRacoonLog();
	void doIptablesRacoon();
	void doIptablesFreeswan();
	void addRouteRacoon();
	void delRouteRacoon();
	void removeIptablesRacoon();
	void removeIptablesFreeswan();
	void removeSetkey();
	void connectionEnded();
	void doPingTest();
	void pingTestExited();
	void sshExited();
	void vpncStarted();
	void ipsecStarted();
	void ipsecPhase2Established();
	void checkIpsecWhackStatus();
	void addIpsecConnection();
	void racoonStarted();
	void pppdStarted();
	void openvpnStarted();
	void openSSLEnded();
	void importCertClicked();
	void manageCiscoCertClicked();
	void enrollCiscoCertClicked();
	void showProfileManagerClicked();
	void executeCommandBeforeConnect();
	void executeCommandAfterConnect();
	void executeCommandBeforeDisconnect();
	void executeCommandAfterDisconnect();
	void setFirewallAfterConnect();
	void setFirewallBeforeDisconnect();
	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 backupIpsecSystemConfig(); // backup ipsec.conf and  ipsec.secrets
	void backupDefaultRoute();
	void exportOpenvpnProfileClicked();
	void addFeatureList( KFeedbackQuestion * question );
	void sendFeedbackMail();
	void feedbackMailSent();
	void start_l2tpd();
	bool checkCiscoVpncStatus();
	void startCiscoVpnc();
	void startStopIpsec(bool stop=false, bool silent=false);
	void startStopOpenl2tp(bool stop=false, bool silent=false);

signals:
        void L2tpdStdoutRecieved();
	void L2tpdStderrRecieved();
	
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

