/***************************************************************************
 *   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 <tqgroupbox.h>
#include <tqstringlist.h>
#include <tqpopupmenu.h>
#include <tqcursor.h>

#include <kpushbutton.h>
#include <tdelistview.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <kcombobox.h>
#include <kurlrequester.h>
#include <kpassdlg.h>


#include <iostream>

ManageCiscoCert::ManageCiscoCert(TQWidget *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,TQ_SIGNAL(clicked()),this,TQ_SLOT(importCertClicked()));
	connect (main->DeleteCertPushButton,TQ_SIGNAL(clicked()),this,TQ_SLOT(deleteCertClicked()));
	connect (main->CertListView,TQ_SIGNAL(contextMenuRequested ( TQListViewItem *, const TQPoint &, int )),this,TQ_SLOT(contextMenuRequested ( TQListViewItem *, const TQPoint &, int )));
	checkList();
}


ManageCiscoCert::~ManageCiscoCert()
{
}

void ManageCiscoCert::deleteCertClicked()
{
	if ( main->CertListView->childCount() > 0 && main->CertListView->currentItem()!= 0 )
	{
		TQListViewItem *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: "+ TQString().setNum(result), GlobalConfig->debug ) ;
		if ( result == 3) // Yes
		{
			

			DeleteProcess = new TQProcess(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, TQ_SIGNAL ( readyReadStdout() ), this, TQ_SLOT ( readFromStdout_remove() ) );
			connect ( DeleteProcess, TQ_SIGNAL ( readyReadStderr() ), this, TQ_SLOT ( readFromStderr_remove() ) );
			connect ( DeleteProcess, TQ_SIGNAL ( processExited()) , this, TQ_SLOT(deleteProcessFinished()));

			TQStringList *env = new TQStringList();
			*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 );

				TQString 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( password+"\n");
				while (DeleteProcess->isRunning())
				{
					sleep(1);
				}

					checkList();
					disconnect ( DeleteProcess, TQ_SIGNAL ( readyReadStdout() ), this, TQ_SLOT ( readFromStdout_remove() ) );
					disconnect ( DeleteProcess, TQ_SIGNAL ( readyReadStderr() ), this, TQ_SLOT ( readFromStderr_remove() ) );
					disconnect ( DeleteProcess, TQ_SIGNAL ( processExited()) , this, TQ_SLOT(deleteProcessFinished()));
					delete DeleteProcess;
					DeleteProcess=0L;
				}
				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->PrivateKeyPassGroupBox->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 )
	{
		TQListViewItem *item = main->CertListView->currentItem();
		CertDataName=item->text(1);
		CertStartFound=false;

		ShowProcess = new TQProcess(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, TQ_SIGNAL ( readyReadStdout() ), this, TQ_SLOT ( readFromStdout_display() ) );
		connect ( ShowProcess, TQ_SIGNAL ( readyReadStderr() ), this, TQ_SLOT ( readFromStderr_display() ) );
		connect ( ShowProcess, TQ_SIGNAL ( processExited()) , this, TQ_SLOT(showProcessFinished()));

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

	GlobalConfig->appPointer->setOverrideCursor( TQCursor(TQt::WaitCursor) );
	if (GlobalConfig->KvpncDebugLevel > 2)
		GlobalConfig->appendLogEntry(i18n("Getting cert info from Cisco certificate store..."), GlobalConfig->debug);
	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 );
			while (ShowProcess->isRunning())
			{
				usleep(200);
				GlobalConfig->appPointer->processEvents();
			}
		}
		disconnect ( ShowProcess, TQ_SIGNAL ( readyReadStdout() ), this, TQ_SLOT ( readFromStdout_display() ) );
		disconnect ( ShowProcess, TQ_SIGNAL ( readyReadStderr() ), this, TQ_SLOT ( readFromStderr_display() ) );
		disconnect ( ShowProcess, TQ_SIGNAL ( processExited()) , this, TQ_SLOT(showProcessFinished()));
		
	}
}

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

void ManageCiscoCert::showProcessFinished()
{
	GlobalConfig->appPointer->restoreOverrideCursor();
	if (GlobalConfig->KvpncDebugLevel > 2)
		GlobalConfig->appendLogEntry(i18n("Done."), GlobalConfig->debug);
	
	GlobalConfig->slotStatusMsg(i18n("Done."), ID_FLASH_MSG);
	GlobalConfig->slotStatusMsg(i18n("Ready."), ID_STATUS_MSG);
		
	delete ShowProcess;
	ShowProcess=0L;
	std::cout << "certdatalist" << CertDataList.join (" ").local8Bit() << 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();

	GlobalConfig->appPointer->setOverrideCursor( TQCursor(TQt::WaitCursor) );
	
	GlobalConfig->slotStatusMsg(i18n("Collecting cisco certs from Cisco certificate store..."), ID_STATUS_MSG);
	if (GlobalConfig->KvpncDebugLevel > 2)
		GlobalConfig->appendLogEntry(i18n("Looking for certs in Cisco certificate store..."), GlobalConfig->debug);

	TQStringList CiscoCerts  = Utils(GlobalConfig).getCertsFromCiscoCertStore("user");
	if (GlobalConfig->KvpncDebugLevel > 2)
		GlobalConfig->appendLogEntry(i18n("Done."), GlobalConfig->debug);
	
	GlobalConfig->slotStatusMsg(i18n("Collecting cisco CA certs from Cisco certificate store..."), ID_STATUS_MSG);
	if (GlobalConfig->KvpncDebugLevel > 2)
		GlobalConfig->appendLogEntry(i18n("Looking for CA certs in Cisco certificate store..."), GlobalConfig->debug);
	TQStringList CiscoCaCerts  = Utils(GlobalConfig).getCertsFromCiscoCertStore("ca");
	if (GlobalConfig->KvpncDebugLevel > 2)
		GlobalConfig->appendLogEntry(i18n("Done."), GlobalConfig->debug);

	GlobalConfig->slotStatusMsg(i18n("Done."), ID_FLASH_MSG);
	GlobalConfig->slotStatusMsg(i18n("Ready."), ID_STATUS_MSG);
	
	main->CertListView->takeItem(main->CertListView->currentItem());
	int current_user_idx=0;
	int current_ca_idx=0;
	for ( TQStringList::Iterator it = CiscoCerts.begin(); it != CiscoCerts.end(); ++it )
	{
		if (GlobalConfig->KvpncDebugLevel > 2)
			std::cout << "insert item (cisco certs):  " << TQString(*it).local8Bit() << std::endl;
		main->CertListView->insertItem( new TQListViewItem(main->CertListView, TQString().setNum(current_user_idx),TQString(*it),i18n("User")));
		current_user_idx++;
	}
	for ( TQStringList::Iterator it = CiscoCaCerts.begin(); it != CiscoCaCerts.end(); ++it )
	{
		if (GlobalConfig->KvpncDebugLevel > 2)
			std::cout << "insert item (cisco certs):  " << TQString(*it).local8Bit() << std::endl;
		main->CertListView->insertItem( new TQListViewItem(main->CertListView, TQString().setNum(current_ca_idx),TQString(*it),i18n("CA")));
		current_ca_idx++;
	}


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

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

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

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

}

void ManageCiscoCert::readFromStdout_display()
{
	while ( ShowProcess->canReadLineStdout() )
	{
		TQString line = TQString ( 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() )
	{
		TQString line = TQString ( ShowProcess->readLineStderr() );
		GlobalConfig->appendLogEntry (  "[cisco_cert_mgr err]: "+line ,GlobalConfig->error );
	}

}

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

void ManageCiscoCert::doContextMenuAction ( int action)
{
	TQString 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();
}

#include "manageciscocert.moc"
