/***************************************************************************
 *   Copyright (C) 2004 by 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 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.             *
 ***************************************************************************/
#include "manageciscocert.h"
#include "utils.h"
#include "importcertificatedialog.h"
#include "displaycertdialog.h"

#include <qgroupbox.h>
#include <qstringlist.h>
#include <qpopupmenu.h>

#include <kpushbutton.h>
#include <klistview.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kcombobox.h>
#include <kurlrequester.h>
#include <kpassdlg.h>

#include <iostream>

ManageCiscoCert::ManageCiscoCert(QWidget *parent, const char* caption, KVpncConfig *GlobalConfig) : KDialogBase (parent, i18n ( "Manage Cisco certificates..." ).ascii(), true, caption, KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true)
{
	main = new ManageCiscoCertBase ( this );
	setMainWidget ( main );
	main->sizeHint();
// 	main->show();
// 	main->setMinimumSize ( main->sizeHint() );
	sizeHint();

	this->GlobalConfig = GlobalConfig;
	connect (main->ImportCertFilePushButton,SIGNAL(clicked()),this,SLOT(importCertClicked()));
	connect (main->DeleteCertPushButton,SIGNAL(clicked()),this,SLOT(deleteCertClicked()));
	connect (main->CertListView,SIGNAL(contextMenuRequested ( QListViewItem *, const QPoint &, int )),this,SLOT(contextMenuRequested ( QListViewItem *, const QPoint &, int )));
	checkList();
}


ManageCiscoCert::~ManageCiscoCert()
{
}

void ManageCiscoCert::deleteCertClicked()
{
	if ( main->CertListView->childCount() > 0 && main->CertListView->currentItem()!= 0 )
	{
		QListViewItem *item = main->CertListView->currentItem();
		
		int result = KMessageBox::questionYesNo ( this, i18n( "Do you really want to delete the cert \"%1\" (type: %2) from cert store?" ).arg(item->text(1).arg(item->text(2))), i18n( "Delete certificate?" ) );

// 		if ( GlobalConfig->KvpncDebugLevel > 2 )
// 			GlobalConfig->appendLogEntry( "Result: "+ QString().setNum(result), GlobalConfig->debug ) ;
		if ( result == 3) // Yes
		{
			

			DeleteProcess = new QProcess(0);
			DeleteProcess->addArgument ( GlobalConfig->pathToCiscoCertMgr );

			if (item->text(2) == i18n("User"))
				DeleteProcess->addArgument ( "-U" );
			if (item->text(2) == i18n("CA"))
				DeleteProcess->addArgument ( "-R" );
			DeleteProcess->addArgument ( "-op" );
			DeleteProcess->addArgument ( "delete" );
			DeleteProcess->addArgument ( "-ct" );
			DeleteProcess->addArgument ( item->text(0) );

			connect ( DeleteProcess, SIGNAL ( readyReadStdout() ), this, SLOT ( readFromStdout_remove() ) );
			connect ( DeleteProcess, SIGNAL ( readyReadStderr() ), this, SLOT ( readFromStderr_remove() ) );
			connect ( DeleteProcess, SIGNAL ( processExited()) , this, SLOT(deleteProcessFinished()));

			QStringList *env = new QStringList();
			*env << "LC_ALL=C" << "LANG=C" << "PATH=/bin:/usr/bin:/usr/sbin:/sbin";

			if ( !DeleteProcess->start ( env ) )
			{

			KMessageBox::sorry ( this, i18n ( "Unable to start process (%1)!" ).arg ( "cisco_cert_mgr" ) );
// 			GlobalConfig->appPointer->restoreOverrideCursor();
			}		
			else
			{
				if ( GlobalConfig->KvpncDebugLevel > 2 )
					GlobalConfig->appendLogEntry ( i18n ( "Process (%1) started." ).arg ("cisco_cert_mgr" ),GlobalConfig->debug );

				QCString password;
				int result = KPasswordDialog::getPassword(password, i18n("Certificate password"));

				if (result == KPasswordDialog::Accepted)
				{

				if ( GlobalConfig->KvpncDebugLevel > 2 )
					GlobalConfig->appendLogEntry ( i18n ( "Certicate password got from user, send it..." ),GlobalConfig->debug );

					DeleteProcess->writeToStdin( QString(password)+"\n");

					checkList();
				}
				else
				{

					// nothing
				}

			}
		}
		
	}
}

void ManageCiscoCert::importCertClicked()
{
	ImportCertificateDialog dlg ( this, i18n ( "Import Certificate..." ).ascii(), GlobalConfig );
	dlg.main->ImporttypeComboBox->setCurrentItem ( ImportCertificateDialog::cisco );
	dlg.typeToggeled ( VpnAccountData::ciscoorig);
	dlg.main->ImporttypeComboBox->setEnabled ( false );
	dlg.main->P12GroupBox->setTitle ( i18n ( "Import" ) );
	dlg.main->CertPathTextLabel->hide();
	dlg.main->RacoonCertificatePathUrlrequester->hide();
	dlg.main->FreeswanGroupBox->setTitle ( i18n ( "Certificate protection" ) );
	dlg.main->PrivateKeyPassTextLabel->setText(i18n ("Certificate password:"));
	dlg.main->PrivateKeyPassAgainTextLabel->setText(i18n ("Certificate password again:"));
	dlg.main->FilenameUrlrequester->setFilter ( "*" );
	//int result =
	dlg.exec();

	checkList();
}

void ManageCiscoCert::showCertClicked()
{
	if ( main->CertListView->childCount() > 0 && main->CertListView->currentItem()!= 0 )
	{
		QListViewItem *item = main->CertListView->currentItem();
		CertDataName=item->text(1);
		CertStartFound=false;

		ShowProcess = new QProcess(0);
		ShowProcess->addArgument ( GlobalConfig->pathToCiscoCertMgr );

		if (item->text(2) == i18n("User"))
		{
			ShowProcess->addArgument ( "-U" );
			CertType=i18n("User certificate");
		}
		if (item->text(2) == i18n("CA"))
		{
			ShowProcess->addArgument ( "-R" );
			CertType=i18n("CA certificate");
		}
		ShowProcess->addArgument ( "-op" );
		ShowProcess->addArgument ( "view" );
		ShowProcess->addArgument ( "-ct" );
		ShowProcess->addArgument ( item->text(0) );

		connect ( ShowProcess, SIGNAL ( readyReadStdout() ), this, SLOT ( readFromStdout_display() ) );
		connect ( ShowProcess, SIGNAL ( readyReadStderr() ), this, SLOT ( readFromStderr_display() ) );
		connect ( ShowProcess, SIGNAL ( processExited()) , this, SLOT(showProcessFinished()));

		QStringList *env = new QStringList();
		*env << "LC_ALL=C" << "LANG=C" << "PATH=/bin:/usr/bin:/usr/sbin:/sbin";

		if ( !ShowProcess->start ( env ) )
		{

		KMessageBox::sorry ( this, i18n ( "Unable to start process (%1)!" ).arg ( "cisco_cert_mgr" ) );
		}
		else
		{
			if ( GlobalConfig->KvpncDebugLevel > 2 )
				GlobalConfig->appendLogEntry ( i18n ( "Process (%1) started." ).arg ("cisco_cert_mgr" ),GlobalConfig->debug );
		}

	}
}

void ManageCiscoCert::deleteProcessFinished()
{
// 	delete DeleteProcess;
	checkList();
}

void ManageCiscoCert::showProcessFinished()
{
	delete ShowProcess;
	std::cout << "certdatalist" << CertDataList.join (" ") << std::endl;
	DisplayCertDialog dlg(0,i18n("Certificate data"),GlobalConfig);
	dlg.main->CertNameTextLabel->setText(CertDataName);
	dlg.main->CertTypeTextLabel->setText(CertType);
	dlg.CertDataList = CertDataList;
	dlg.parseCertData();
	dlg.exec();
	CertDataName="";
	CertDataList.clear();
}

void ManageCiscoCert::checkList()
{
	main->CertListView->clear();

	QStringList CiscoCerts  = Utils(GlobalConfig).getCertsFromCiscoCertStore("user");
	QStringList CiscoCaCerts  = Utils(GlobalConfig).getCertsFromCiscoCertStore("ca");
	main->CertListView->takeItem(main->CertListView->currentItem());
	int current_user_idx=0;
	int current_ca_idx=0;
	for ( QStringList::Iterator it = CiscoCerts.begin(); it != CiscoCerts.end(); ++it )
	{
		if (GlobalConfig->KvpncDebugLevel > 2)
			std::cout << "insert item (cisco certs):  " << QString(*it) << std::endl;
		main->CertListView->insertItem( new QListViewItem(main->CertListView, QString().setNum(current_user_idx),QString(*it),i18n("User")));
		current_user_idx++;
	}
	for ( QStringList::Iterator it = CiscoCaCerts.begin(); it != CiscoCaCerts.end(); ++it )
	{
		if (GlobalConfig->KvpncDebugLevel > 2)
			std::cout << "insert item (cisco certs):  " << QString(*it) << std::endl;
		main->CertListView->insertItem( new QListViewItem(main->CertListView, QString().setNum(current_ca_idx),QString(*it),i18n("CA")));
		current_ca_idx++;
	}


	if (main->CertListView->childCount() > 0 && main->CertListView->currentItem()!= 0 )
	{
		main->DeleteCertPushButton->setEnabled(true);
	}
	else
	{
		main->DeleteCertPushButton->setEnabled(false);
	}
}

void ManageCiscoCert::readFromStdout_remove()
{
	while ( DeleteProcess->canReadLineStdout() )
	{
		QString line = QString ( DeleteProcess->readLineStdout() );

		if ( GlobalConfig->KvpncDebugLevel > 2 )
			GlobalConfig->appendLogEntry ( "[cisco_cert_mgr]: "+line,GlobalConfig->debug );
	}
}

void ManageCiscoCert::readFromStderr_remove()
{
	while ( DeleteProcess->canReadLineStderr() )
	{
		QString line = QString ( DeleteProcess->readLineStderr() );
		GlobalConfig->appendLogEntry (  "[cisco_cert_mgr err]: "+line ,GlobalConfig->error );
	}
	checkList();

}

void ManageCiscoCert::readFromStdout_display()
{
	while ( ShowProcess->canReadLineStdout() )
	{
		QString line = QString ( ShowProcess->readLineStdout() );

		if ( GlobalConfig->KvpncDebugLevel > 2 )
			GlobalConfig->appendLogEntry ( "[cisco_cert_mgr]: "+line,GlobalConfig->debug );

		if (CertStartFound)
			CertDataList.append(line);
		else
		{
			if ( line.find ( "Common Name:" , 0, FALSE ) > -1)
			{

				if ( GlobalConfig->KvpncDebugLevel > 2 )
					GlobalConfig->appendLogEntry ( i18n("Cert start found."),GlobalConfig->debug );


				CertStartFound=true;
				CertDataList.append(line);
			}
		}
	}
}

void ManageCiscoCert::readFromStderr_display()
{
	while ( ShowProcess->canReadLineStderr() )
	{
		QString line = QString ( ShowProcess->readLineStderr() );
		GlobalConfig->appendLogEntry (  "[cisco_cert_mgr err]: "+line ,GlobalConfig->error );
	}

}

void ManageCiscoCert::contextMenuRequested ( QListViewItem * item, const QPoint &pos, int )
{
	ContextMenu = new QPopupMenu ( 0 );
	if (item != 0)
	{
		ContextMenu->insertItem(i18n("&Show..."));
		ContextMenu->insertSeparator();
		ContextMenu->insertItem(i18n("&Delete..."));
	}
	ContextMenu->insertItem(i18n("&Add..."));
	connect ( ContextMenu, SIGNAL ( activated ( int ) ), this, SLOT ( doContextMenuAction ( int ) ) );
	ContextMenu->show();
	ContextMenu->setGeometry(pos.x(),pos.y(), ContextMenu->width(),ContextMenu->height());
}

void ManageCiscoCert::doContextMenuAction ( int action)
{
	QString itemtext = ContextMenu->text ( action );
// 	std::cout << "action: " << itemtext << std::endl;
	if (itemtext == i18n("&Delete..."))
		deleteCertClicked();
	if (itemtext == i18n("&Add..."))
		importCertClicked();
	if (itemtext == i18n("&Show..."))
		showCertClicked();
}

