/*****************************************************************************
 * Copyright (C) 2004-2009 Christoph Thielecke <crissi99@gmx.de>             *
 *                                                                           *
 * 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 package 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 package; if not, write to the Free Software               *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include "importprofiledialog.h"

#include <QTextStream>
#include <QUrl>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtGui/QCheckBox>

#include <kconfig.h>
#include <kconfiggroup.h>
#include <kdialog.h>
#include <kio/netaccess.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <ktemporaryfile.h>
#include <kurl.h>
#include <kurlrequester.h>
#include <kcombobox.h>



#include <string>

#include "ciscopasswddecoder.h"
#include "utils.h"
#include "importcertificatedialog.h"

ImportProfileDialog::ImportProfileDialog(KVpncConfig *GlobalConfig, QWidget *parent, const QString& caption, QString file)
        : KDialog(parent)
{
    Q_UNUSED(caption);

    QWidget *page = new QWidget(this);
    setMainWidget(page);
    setupUi(page);
    decodeEncPasswd = false;
    if (!file.isEmpty())
        filename = file;
    else
        filename = "";
    importOk = false;
    this->GlobalConfig = GlobalConfig;


    FilenameUrlrequester->setFilter("*.pcf");
    FilenameUrlrequester->setUrl(filename);

}


ImportProfileDialog::~ImportProfileDialog()
{
}

void ImportProfileDialog::accept()
{

    //filename="/etc/CiscoSystemsVPNClient/Profiles/hs_harz.pcf";
    filename = FilenameUrlrequester->url().toLocalFile();
    if (!filename.isEmpty()) {
        f = new QFile(filename);
        canAccept();
    }

    else {
        KMessageBox::sorry(0, i18n("Filename cannot be empty."), i18n("Empty Filename"));
    }
}


void ImportProfileDialog::canAccept()
{

    if (!f->exists()) {
        KMessageBox::information(0, i18n("File not found."), i18n("No File"));

        //  emit progress( 100 );
        return ;
    }

    KConfig confighandle(filename, KConfig::SimpleConfig);

    QStringList grouplist = confighandle.groupList();

    if (GlobalConfig->KvpncDebugLevel > 0) {
        QString groups = "";
        for (QStringList::Iterator group = grouplist.begin(); group != grouplist.end(); ++group)
            groups += QString(" " + *group);
        GlobalConfig->appendLogEntry(i18n("PCF import: groups found: [ %1 ]", groups), KVpncEnum::debug);
    }
    KConfigGroup config = confighandle.group("main");

    // sample config

    /*
    [main]
    Description=
    Host=192.168.13.1
    AuthType=1
    GroupName = hs_harz
    GroupPwd =
    Username = u15119
    SaveUserPassword = 0
    UserPassword =
    NTDomain =
    EnableBackup = 0
    BackupServer =
    EnableMSLogon = 1
    TunnelingMode = 0
    TcpTunnelingPort = 10000
    CertStore = 0
    CertName =
    CertPath =
    CertSubjectName =
    CertSerialHash = 00000000000000000000000000000000
    SendCertChain = 0
    VerifyCertDN =
    DHGroup = 2
    ForceKeepAlives = 0
    PeerTimeout = 90
    EnableLocalLAN = 1 // only reading because we do not want to do this
    EnableSplitDNS = 1
    EnableNAT = 1
    */
	
	VpnAccountData::ConnectionType ConnType = VpnAccountData::cisco;
	QString ProfileName = QFileInfo ( f->name().stripWhiteSpace().remove(".pcf").remove(".PCF") ).fileName();
	acc = new VpnAccountData ( ConnType, Utils(this->GlobalConfig).removeSpecialCharsForFilename( ProfileName ));
	
    QString Description = config.readEntry("Description", "");

    if (Description.isEmpty())
        Description = config.readEntry("!Description", i18n("Profile imported from file %1.", filename));

    if (!Description.isEmpty()) {
        if (GlobalConfig->KvpncDebugLevel > 0)
            GlobalConfig->appendLogEntry(i18n("PCF import: description found: %1", Description), KVpncEnum::debug);
		acc->setDescription( Description );
    }

    QString Gateway = config.readEntry("Host", "");

    if (Gateway.isEmpty())
        Gateway = config.readEntry("!Host", "");

    if (!Gateway.isEmpty()) {
        if (GlobalConfig->KvpncDebugLevel > 0)
            GlobalConfig->appendLogEntry(i18n("PCF import: gateway found: %1", Gateway), KVpncEnum::debug);
		acc->setGateway( Gateway );
    }
    if (GlobalConfig->KvpncDebugLevel > 4) {
        GlobalConfig->appendLogEntry(i18n("PCF import: gateway: %1", Gateway), KVpncEnum::debug);
    }
    

	bool useApplicationVersion = false;
	acc->setUseApplicationVersion( useApplicationVersion );

	bool enableBackup = QVariant(config.readEntry( "EnableBackup" , FALSE )).toBool();
	QString BackupServer = config.readEntry( "BackupServer", "" );

	QString GroupName = config.readEntry( "GroupName" , "" );
	
	if (GroupName.isEmpty())
		GroupName = config.readEntry( "!GroupName", "" );
	
	if (GroupName.isEmpty())
		GroupName = "importedProfile";
	
	if (!GroupName.isEmpty())
	{
		if (GlobalConfig->KvpncDebugLevel > 0)
			GlobalConfig->appendLogEntry(i18n("PCF import: group name found: %1", GroupName), KVpncEnum::debug);
		acc->setID( GroupName );
	}
	
	QString NtDomain = config.readEntry( "NTDomain" );
	if (NtDomain.isEmpty())
		NtDomain = config.readEntry( "!NTDomain", "" );
	
	if (!NtDomain.isEmpty())
	{
		if (GlobalConfig->KvpncDebugLevel > 0)
			GlobalConfig->appendLogEntry(i18n("PCF import: NT domain found: %1", NtDomain), KVpncEnum::debug);
		acc->setNtDomainName( NtDomain );
	}
	
	bool enableMSLogon = QVariant(config.readEntry( "EnableMSLogon", FALSE )).toBool();
	bool useNtDomainName = false;
	
	if ( enableMSLogon && !NtDomain.isEmpty() )
		useNtDomainName = true;
	
	QString CertName = config.readEntry( "CertName", "" );
	
	if (GlobalConfig->KvpncDebugLevel > 0)
		GlobalConfig->appendLogEntry(i18n("PCF import: certificate name found: %1", CertName), KVpncEnum::debug);
	
	QString CertPath = config.readEntry( "CertPath", "" );
	QString CertSubjectName = config.readEntry( "CertSubjectName", "" );
	QString CertSerialHash = config.readEntry( "CertSerialHash", "" );
	//	bool SendCertChain = QVariant(config.readEntry( "SendCertChain" , "" )).toInt();
	//	bool VerifyCertDN = QVariant(config.readEntry( "VerifyCertDN", FALSE )).toInt();
	
	/*
	0 = default, none
	1 = Cisco
	*/
	bool useCertStore=false;
	int CertStore = QVariant(config.readEntry( "CertStore", -1 )).toInt();
	if (CertStore == 1)
		useCertStore = true;
	if (GlobalConfig->KvpncDebugLevel > 0)
		GlobalConfig->appendLogEntry(i18n("PCF import: certificate should be stored into cisco cert store: %1", QString().setNum(int(useCertStore))), KVpncEnum::debug);
	
	if (useCertStore)
	{
		// we have to import into the store
		if (!CertName.isEmpty())
		{
			bool CertPathFound = false;
			QString CertFullPath = CertName;
			if (!QFile(CertFullPath).exists())
			{
				CertFullPath = CertPath+"/"+CertName;
				if (!QFile(CertFullPath).exists())
				{
					GlobalConfig->appendLogEntry(i18n("Cisco certificate import: cert not found, skipping."), KVpncEnum::error);
				}
				else
				{
					if (GlobalConfig->KvpncDebugLevel > 0)
						GlobalConfig->appendLogEntry(i18n("Cisco certificate import: cert found at current path."), KVpncEnum::debug);
					CertPathFound = true;
				}
			}
			else
			{
				if (GlobalConfig->KvpncDebugLevel > 0)
					GlobalConfig->appendLogEntry(i18n("Cisco certificate import: cert found at cert path."), KVpncEnum::debug);
				CertPathFound = true;
				
			}
			if (CertPathFound)
			{
				QStringList OldCiscoCerts  = Utils(GlobalConfig).getCertsFromCiscoCertStore();
				ImportCertificateDialog dlg( this, i18n( "Import certificate..." ).ascii(), GlobalConfig );
				dlg.main->FilenameUrlrequester->setUrl(CertFullPath);
				dlg.main->ImporttypeComboBox->setCurrentIndex(dlg.ciscouserca); // import user and ca cert
				int result = dlg.exec();
				if (result == QDialog::Accepted)
				{
					acc->setUseCiscoCertStore(true);
					QStringList CiscoCerts  = Utils(GlobalConfig).getCertsFromCiscoCertStore();
					for ( QStringList::Iterator ciscoit = CiscoCerts.begin(); ciscoit != CiscoCerts.end(); ++ciscoit )
					{
						if (OldCiscoCerts.findIndex(QString(*ciscoit)) < 1 )
						{
							// if it was not in list, then its the new added one.
							acc->setX509Certificate(*ciscoit);
							break;
						}
					}
				}
			}
		}
	}
	{
		acc->setX509Certificate(CertName);
		acc->setCertPath(CertPath);
	}
	
	
	int TcpTunnelingPort = QVariant(config.readEntry( "TcpTunnelingPort", 10000 )).toInt(); //std::cout << "tunneling port: " << TunnelingPort << std::endl;
	/*
	0, the default, specifies IPSec over UDP for NAT transparency
	1 specifies IPSec over TCP for NAT transparency
	*/
	bool useUdp = QVariant(config.readEntry( "TunnelingMode", 0 )).toBool();
	acc->setUseUdp( useUdp );
	
	int LocalPort=10000;
	bool useLocalPort = false;
	if (TcpTunnelingPort != 10000)
		useLocalPort = true;
	
	if (useLocalPort && useUdp == false)
	{
		acc->setLocalPort(LocalPort);
		acc->setUseLocalPort(true);
	}
	
	
	//	bool ForceKeepAlives = QVariant(config.readEntry( "ForceKeepAlives", FALSE )).toBool();
	
	//	bool EnableLocalLAN = QVariant(config.readEntry( "EnableLocalLAN", FALSE )).toBool(); // nur auslesen aber immer aus :)
					//	bool EnableSplitDNS = QVariant(config.readEntry( "EnableSplitDNS", FALSE );
					
					
					if (useUdp == false)
					{
						// vpnc does not support TCP :(
						acc->setConnectionType(VpnAccountData::cisco);
					}
					if (useUdp)
					{
						if (GlobalConfig->KvpncDebugLevel > 0)
							GlobalConfig->appendLogEntry(i18n("PCF import: using %1 for tunneling", QString("UDP")), KVpncEnum::debug);
						acc->setUseUdp( true);
					}
					else
					{
						if (GlobalConfig->KvpncDebugLevel > 0)
							GlobalConfig->appendLogEntry(i18n("PCF import: using %1 for tunneling", QString("TCP")), KVpncEnum::debug);
						acc->setUseUdp( false);
					}
					/*
					0, the default, disables IPSec through NAT mode
					1 enables IPSec through NAT mode
					*/
					
					bool enableNAT = QVariant(config.readEntry("EnableNat", false)).toBool();
					if (enableNAT)
					{
						if (GlobalConfig->KvpncDebugLevel > 0)
							GlobalConfig->appendLogEntry(i18n("PCF import: enable NAT mode : %1", i18n("yes")), KVpncEnum::debug);
						acc->setUseNat(true);
					}
					else
					{
						if (GlobalConfig->KvpncDebugLevel > 0)
							GlobalConfig->appendLogEntry(i18n("PCF import: enable NAT mode : %1", i18n("no")), KVpncEnum::debug);
						acc->setUseNat(false);
					}
					
					bool useUdpPort= true;
					
					
					// 	if ( TunnelingPort != 10000 )
					// 	{
						// 		useUdp=true; //FIXME: is this right? I guess its only on udp
						// 		useUdpPort = true;
						// 	}
						
						QString PerfectForwardSecrecy = ""; //QString("dh"+QString().setNum(DHGroup));
						//	bool usePerfectForwardSecrety = false;
						bool usePerfectSecrecy = false;
						acc->setPerfectForwardSecrety( PerfectForwardSecrecy );
						acc->setUsePerfectForwardSecrety( usePerfectSecrecy );
						bool useIkeGroup = false;
						QString IkeGroup;
						int DHGroup = QVariant(config.readEntry( "DHGroup", -1 )).toInt();
						if (DHGroup != -1 )
						{
							if (GlobalConfig->KvpncDebugLevel > 0)
								GlobalConfig->appendLogEntry(i18n("PCF import: Diffie Hellman group found: %1", QString().setNum(DHGroup)), KVpncEnum::debug);
							IkeGroup =  "dh" + QString().setNum( DHGroup ) ;
							useIkeGroup = true;
							acc->setIkeGroup( IkeGroup );
						}
						
						int PeerTimeout = QVariant(config.readEntry( "PeerTimeout", -1 )).toInt();
						if (PeerTimeout > -1 )
						{
							if (GlobalConfig->KvpncDebugLevel > 0)
								GlobalConfig->appendLogEntry(i18n("PCF import: peer timeout found: %1", QString().setNum(PeerTimeout)), KVpncEnum::debug);
							// read minutes but store seconds
							acc->setPeerTimeout( PeerTimeout*60 );
						}
						
						QString Username = config.readEntry( "Username" , "" );
						if (!Username.isEmpty())
						{
							if (GlobalConfig->KvpncDebugLevel > 0)
								GlobalConfig->appendLogEntry(i18n("PCF import: username found: %1", Username), KVpncEnum::debug);
							acc->setUserName( Username );
						}
						
						QString UserPassword = config.readEntry( "UserPassword", "" );
						if (UserPassword.isEmpty())
							UserPassword = config.readEntry( "!UserPassword", "" );
						
						if (!UserPassword.isEmpty())
						{
							if (GlobalConfig->KvpncDebugLevel > 0)
								GlobalConfig->appendLogEntry(i18n("PCF import: clear text user password found: %1", UserPassword), KVpncEnum::debug);
							acc->setUserPassword( UserPassword );
						}
						
						QString enc_UserPassword = config.readEntry( "enc_UserPassword", "" );
						if (enc_UserPassword.isEmpty())
							enc_UserPassword = config.readEntry( "!enc_UserPassword", "" );
						
						if (!enc_UserPassword.isEmpty())
						{
							if (GlobalConfig->KvpncDebugLevel > 0)
								GlobalConfig->appendLogEntry(i18n("PCF import: encrypted user password found: %1", enc_UserPassword), KVpncEnum::debug);
						}
						
						CiscoPasswdDecoder dec (filename);
						QString userpasswd="";
						QString grouppasswd="";
						dec.decodePasswords(userpasswd,grouppasswd);
						
						// 	std::cout << "decoded userpasswd: " << userpasswd << std::endl;
						// std::cout << "decoded grouppasswd: " << grouppasswd << std::endl;
						
						bool saveUserPassword = QVariant(config.readEntry( "SaveUserPassword", FALSE )).toBool();
						
						if (saveUserPassword == false)
							QVariant(config.readEntry( "!SaveUserPassword", FALSE )).toBool();
						
						if ( UserPassword.isEmpty() && userpasswd.isEmpty() )
							saveUserPassword = false;
						
						if (!userpasswd.isEmpty())
						{
							if (GlobalConfig->KvpncDebugLevel > 3)
								GlobalConfig->appendLogEntry(i18n("PCF import: decrypted user password found: %1", userpasswd), KVpncEnum::debug);
							acc->setUserPassword( userpasswd );
						}
						
						if (GlobalConfig->KvpncDebugLevel > 0)
							if (saveUserPassword)
								GlobalConfig->appendLogEntry(i18n("PCF import: save user pass : %1", i18n("yes")), KVpncEnum::debug);
							else
								GlobalConfig->appendLogEntry(i18n("PCF import: save user pass : %1", i18n("no")), KVpncEnum::debug);
							acc->setSaveUserPassword( saveUserPassword );
						
						bool saveGroupPwd = true;
						QString GroupPwd = config.readEntry( "GroupPwd" , "" );
						if (GroupPwd.isEmpty())
							GroupPwd = config.readEntry( "!GroupPwd", "" );
						
						if (!GroupPwd.isEmpty())
						{
							if (GlobalConfig->KvpncDebugLevel > 3)
								GlobalConfig->appendLogEntry(i18n("PCF import: clear text group password found: %1", GroupPwd), KVpncEnum::debug);
							acc->setPreSharedKey( GroupPwd );
						}
						
						QString enc_GroupPwd = config.readEntry( "enc_GroupPwd", "" );
						
						if (enc_GroupPwd.isEmpty())
							enc_GroupPwd = config.readEntry( "!enc_GroupPwd", "" );
						
						if (!grouppasswd.isEmpty())
						{
							if (GlobalConfig->KvpncDebugLevel > 3)
								GlobalConfig->appendLogEntry(i18n("PCF import: decrypted group password found: %1", grouppasswd), KVpncEnum::debug);
							acc->setPreSharedKey( grouppasswd );
						}
						
						if ( GroupPwd.isEmpty() && grouppasswd.isEmpty())
							saveGroupPwd = false;
						acc->setSavePsk( saveGroupPwd );
						
						if ( Description.isEmpty() )
						{
							Description = ( QUrl( filename ).fileName() );
							Description = Utils(this->GlobalConfig).removeSpecialCharsForFilename( Description.left( filename.section('/',-1).length() - 4 ));
						}
						
						if ( GroupName.isEmpty() )
						{
							GroupName = Utils(this->GlobalConfig).removeSpecialCharsForFilename( GroupName.left( filename.section('/',-1).length() - 4 ));
						}
						
						/*
						AuthType=
						The authentication type of the user:
						1 = Pre-shared keys (default)
						3 = Digital Certificate using an RSA signature.
						5 = Mutual authentication (hybrid)
						*/

						/*
						AuthType=
						The authentication type of the user:
						1 = Pre-shared keys (default)
						3 = Digital Certificate using an RSA signature.
						5 = Mutual authentication (hybrid)
						*/
						int AuthType = QVariant(config.readEntry( "AuthType" , -1 )).toInt();
						
						if (AuthType==-1)
							AuthType = QVariant(config.readEntry( "!AuthType", -1 )).toInt();
						
						if (GlobalConfig->KvpncDebugLevel > 0)
							if (AuthType ==1)
								GlobalConfig->appendLogEntry(i18n("PCF import: authentication type found: %1", i18n("PSK")), KVpncEnum::debug);
							else if (AuthType ==3)
								GlobalConfig->appendLogEntry(i18n("PCF import: authentication type found: %1", i18n("certificate")), KVpncEnum::debug);
							else if (AuthType ==5)
								GlobalConfig->appendLogEntry(i18n("PCF import: authentication type found: %1", i18n("hybrid")), KVpncEnum::debug);
							else
								GlobalConfig->appendLogEntry(i18n("PCF import: no authentication type found, assuming %1", i18n("PSK")), KVpncEnum::debug);
							
							if (AuthType == 3 || AuthType == 5)
							{
								// vpnc has no cert support :(
								acc->setConnectionType (VpnAccountData::ciscoorig);
								acc->setAuthType( VpnAccountData::cert);
								
								if (!CertName.isEmpty())
									acc->setX509Certificate(CertName);
							}
							else if (AuthType == 1 )
								acc->setAuthType( VpnAccountData::psk);
							else
								acc->setAuthType( VpnAccountData::psk);
							
							bool useGlobalIpsecSecret = false;
							acc->setUseGlobalIpsecSecret( useGlobalIpsecSecret );
							
							bool useSingleDes = false;
							acc->setUseSingleDes( useSingleDes );
							
							//acc->setUseAdvancedSettings( useAdvancedSettings );
							acc->setUseAdvancedSettings( true );
							
							

    /*
    acc.setName( Description );
    acc.setGateway( Gateway );
    acc.setID( GroupName );
    acc.setGroupPassword( GroupPwd );
    acc.setUserName( Username );
    acc.setUserPassword( UserPassword );
    acc.setSaveUserPassword( saveUserPassword );
    acc.setSaveGroupPassword( true );
    //acc.setIkeGroup( QString IkeGroup );
    acc.setPerfectForwardSecrety( QString PerfectForwardSecrecy );
    acc.setNtDomainName( QString Name );
    acc.setApplicationVersion( QString version );
    acc.setUseSingleDes( bool useSingleDes );
    acc.setLocalPort( int port );
    acc.setUseIkeGroup( bool useIkeGroup);
    acc.setUsePerfectForwardSecrety(bool usePerfectForwardSecrety);
    acc.setUseNtDomainName(bool useNtDomainName);
    acc.setUseApplicationVersion(bool useApplicationVersion);
    acc.setUseLocalPort(bool useLocalPort);
    acc.setUseAdvancedSettings(bool useAdvancedSettings);
    acc.setUseGlobalIpsecSecret(bool useGlobalIpsecSecret);
    */
    importOk = true;
    QDialog::accept();
}

#include "importprofiledialog.moc"
