/*
 *  Copyright (C) 2007-2008 CMM Sigma Andrzej Chmielowiec <cmmsigma@cmmsigma.eu>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 3
 *  as published by the Free Software Foundation.
 *
 *  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.
 */

#include "VpnNewWindow.h"
#include "FileDialogWPR.h"

#include <QtGui>
#include "STokenDialog.h"
#include "ipaddr.h"

VpnNewWindow::VpnNewWindow(QWidget *parent): QDialog(parent)
{
	setWindowTitle(tr("New connection wizard"));
	setWindowIcon(QIcon(QString(":img/vpn_new_22.png")));
	
	mCancel = new QPushButton(tr("Can&cel"));
	connect(mCancel, SIGNAL(clicked()), this, SLOT(reject()));
	
	mSave = new QPushButton(tr("&Save"));
	connect(mSave, SIGNAL(clicked()), this, SLOT(saveSlot()));
	
	QGridLayout *layout = new QGridLayout;
	
	layout->addWidget(createBaseTab(), 0, 0, 1, 3);
	layout->addWidget(mSave, 1, 1);
	layout->addWidget(mCancel, 1, 2);
	
	layout->setColumnStretch(0, 1);
	layout->setRowStretch(0, 1);
	
	setLayout(layout);
}

void
VpnNewWindow::templateBrowseSlot()
{
	QString filePath = FileDialogWPR::getOpenFileName(this, tr("Select file"), 
		QString());
	
	if (filePath != QString())
	{
		QFile file(filePath);
		file.open(QIODevice::ReadOnly);
		mTemplateData = file.readAll();
		file.close();
		
		mTemplateFileName->setText(filePath);
	}
}

#ifndef STOKEN_SOFT
void
VpnNewWindow::templateImportSlot()
{
	QString filePath = STokenDialog::getFileNameAndData(mTemplateData, tr("File selection"), this);
	
	if (filePath != QString())
		mTemplateFileName->setText(filePath);
}

void
VpnNewWindow::caCertImportSlot()
{
	QString filePath = STokenDialog::getFileNameAndData(mCaCertData, tr("Certificate selection"), this);
	
	if (filePath != QString())
	{
		mCaCert->setText(filePath);
		mCaCertFileName = mCaCert->text();
		mCaCertFileName.remove(0, mCaCertFileName.lastIndexOf(QChar('/')) + 1);
	}
}

void
VpnNewWindow::userCertImportSlot()
{
	QString filePath = STokenDialog::getFileNameAndData(mUserCertData, tr("Certificate selection"), this);
	
	if (filePath != QString())
	{
		mUserCert->setText(filePath);
		mUserCertFileName = mUserCert->text();
		mUserCertFileName.remove(0, mUserCertFileName.lastIndexOf(QChar('/')) + 1);
	}
}
#endif

void
VpnNewWindow::caCertBrowseSlot()
{
	QString filePath = FileDialogWPR::getOpenFileName(this, QObject::tr("Select certificate file"), QString(),
		QObject::tr("Certificate files (*.cert);;All files (*)"));

	if (!filePath.isEmpty())
	{
		mCaCertFileName = QFileInfo(filePath).fileName();
		
		QFile file(filePath);
		file.open(QIODevice::ReadOnly);
		mCaCertData = file.readAll();
		file.close();
		
		mCaCert->setText(filePath);
	}
}

void
VpnNewWindow::userCertBrowseSlot()
{
	QString filePath = FileDialogWPR::getOpenFileName(this, QObject::tr("Select certificate file"), QString(),
		QObject::tr("Certificate files (*.cert);;All files (*)"));

	if (!filePath.isEmpty())
	{
		mUserCertFileName = QFileInfo(filePath).fileName();
		
		QFile file(filePath);
		file.open(QIODevice::ReadOnly);
		mUserCertData = file.readAll();
		file.close();
		
		mUserCert->setText(filePath);
	}
}

void
VpnNewWindow::sTokenKeyBrowseSlot()
{
	QString key;
	
#ifndef STOKEN_SOFT
	key = STokenDialog::getKeyName(tr("Key selection"), this);
#else
	key = FileDialogWPR::getOpenFileName(this, tr("Select private key file"),
		QString(), tr("Key files (*.key);;All files (*)"));
#endif
	
	if (!key.isEmpty())
		mKey->setText(key);
}

void
VpnNewWindow::saveSlot()
{
	if (mSTokenVpnName->text().isEmpty())
	{
		QMessageBox::information(this, tr("Missing data"), tr("Enter VPN connection name!"));
		return;
	}
	
	if (mRemoteVpnServer->text().isEmpty())
	{
		QMessageBox::information(this, tr("Missing data"), tr("Enter VPN server name or IP address!"));
		return;
	}
	
	if (mCaCert->text().isEmpty())
	{
		QMessageBox::information(this, tr("Missing data"), tr("Select CA certificate file!"));
		return;
	}
	
	if (mUserCert->text().isEmpty())
	{
		QMessageBox::information(this, tr("Missing data"), tr("Select User certificate file!"));
		return;
	}
	
	if (mKey->text().isEmpty())
	{
		QMessageBox::information(this, tr("Missing data"), tr("Select private key file!"));
		return;
	}
	
	mConfName = newConfName();
	
	if (!QDir(QDir::current().path() + QString("/") + mConfName).exists())
		QDir::current().mkdir(mConfName);
	
	QDir confDir(QDir::current().path() + QString("/") + mConfName);
	QFile conf(confDir.path() + QString("/conf"));
	conf.open(QIODevice::WriteOnly);
	
	QStringList list = mRemoteVpnServer->text().split(QChar(':'));
	
	if (list.size() == 1)
		list.append(QString("1194"));
	
	QString confData = QString(
			"#\n"
			"# sTokenVpnName %1\n"
			"#\n"
			"remote %2\n"
			"rport %3\n"
			"ca ca\n"
			"cert user\n"
			"key %4\n"
		).
		arg(mSTokenVpnName->text()).
		arg(list[0]).
		arg(list[1]).
		arg(mKey->text());
	
	conf.write(confData.toUtf8());
	conf.write(QByteArray("\n#\n# configuration template\n#\n\n"));
	conf.write(mTemplateData);
	conf.close();
	
	QFile caCert(confDir.path() + QString("/ca"));
	caCert.open(QIODevice::WriteOnly);
	caCert.write(mCaCertData);
	caCert.close();
	
	QFile userCert(confDir.path() + QString("/user"));
	userCert.open(QIODevice::WriteOnly);
	userCert.write(mUserCertData);
	userCert.close();
	
	accept();
}

QString
VpnNewWindow::newConfName()
{
	QStringList confs(QDir::current().entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name));
	QList<int> hexConfs;
	int i;
	
	for (i = 0; i < confs.size(); i++)
	{
		bool ok;
		int hex = confs[i].toInt(&ok, 16);
		if (ok) hexConfs.append(hex);
	}
	
	int newConf = 0;
	
	while (1)
	{
		for (i = 0; i < hexConfs.size(); i++)
		{
			if (newConf == hexConfs[i]) break;
		}
		
		if (i == hexConfs.size()) break;
		else newConf += 1;
	}
	
	return QString("%1").arg(newConf, 4, 16, QChar('0'));
}

QWidget*
VpnNewWindow::createBaseTab()
{
	QWidget *tab = new QWidget;
	QGridLayout *layout = new QGridLayout;
	tab->setLayout(layout);
	
	layout->addWidget(createNameBox(), 0, 0);
	layout->addWidget(createNetDetailsBox(), 1, 0);
	layout->addWidget(createCertsKeyBox(), 2, 0);
	layout->setRowStretch(3, 1);
	
	return tab;
}

QGroupBox*
VpnNewWindow::createNameBox()
{
	QGroupBox *box = new QGroupBox(tr("VPN conncetion name"));
	QGridLayout *layout = new QGridLayout;
	box->setLayout(layout);
	
	mSTokenVpnName = new QLineEdit;
	mTemplateFileName = new QLineEdit;
	mTemplateBrowse = new QPushButton(tr("Select"));
	connect(mTemplateBrowse, SIGNAL(clicked()), this, SLOT(templateBrowseSlot()));
#ifndef STOKEN_SOFT
	mTemplateImport = new QPushButton(tr("Import"));
	connect(mTemplateImport, SIGNAL(clicked()), this, SLOT(templateImportSlot()));
#endif
	
	layout->addWidget(new QLabel(tr("Connection name<sup>*</sup>")), 0, 0);
	layout->addWidget(mSTokenVpnName, 0, 1, 1, 3);
	layout->addWidget(new QLabel(tr("Connection template file")), 2, 0);
#ifndef STOKEN_SOFT
	layout->addWidget(mTemplateFileName, 2, 1, 1, 3);
	layout->addWidget(mTemplateBrowse, 3, 2);
	layout->addWidget(mTemplateImport, 3, 3);
#else
	layout->addWidget(mTemplateFileName, 2, 1, 1, 3);
	layout->addWidget(mTemplateBrowse, 3, 3);
#endif

	layout->setColumnStretch(1, 1);
	
	return box;
}

QGroupBox*
VpnNewWindow::createNetDetailsBox()
{
	QGroupBox *box = new QGroupBox(tr("VPN server"));
	QGridLayout *layout = new QGridLayout;
	box->setLayout(layout);
	
	mRemoteVpnServer = new QLineEdit;
	
	layout->addWidget(new QLabel(tr("VPN server name or IP address<sup>*</sup>")), 0, 0);
	layout->addWidget(mRemoteVpnServer, 0, 1);
	layout->setColumnStretch(1, 1);
	
	return box;
}

QGroupBox*
VpnNewWindow::createCertsKeyBox()
{
	QGroupBox *box = new QGroupBox(tr("Certificates and key"));
	QGridLayout *layout = new QGridLayout;
	box->setLayout(layout);
	
	mCaCert = new QLineEdit;
	mCaCertBrowse = new QPushButton(tr("Select"));
	connect(mCaCertBrowse, SIGNAL(clicked()), this, SLOT(caCertBrowseSlot()));
#ifndef STOKEN_SOFT
	mCaCertImport = new QPushButton(tr("Import"));
	connect(mCaCertImport, SIGNAL(clicked()), this, SLOT(caCertImportSlot()));
	mUserCertImport = new QPushButton(tr("Import"));
	connect(mUserCertImport, SIGNAL(clicked()), this, SLOT(userCertImportSlot()));
#endif	
	mUserCert = new QLineEdit;
	mUserCertBrowse = new QPushButton(tr("Select"));
	connect(mUserCertBrowse, SIGNAL(clicked()), this, SLOT(userCertBrowseSlot()));
	
	mKey = new QLineEdit;
	mKeyBrowse = new QPushButton(tr("Select"));
	connect(mKeyBrowse, SIGNAL(clicked()), this, SLOT(sTokenKeyBrowseSlot()));
	
	layout->addWidget(new QLabel(tr("CA certificate<sup>*</sup>")), 0, 0);
	layout->addWidget(new QLabel(tr("User certificate<sup>*</sup>")), 2, 0);
	layout->addWidget(mCaCert, 0, 1, 1, 3);
	layout->addWidget(mUserCert, 2, 1, 1, 3);

#ifndef STOKEN_SOFT
	layout->addWidget(mCaCertBrowse, 1, 2);
	layout->addWidget(mCaCertImport, 1, 3);
	layout->addWidget(mUserCertBrowse, 3, 2);
	layout->addWidget(mUserCertImport, 3, 3);
#else
	layout->addWidget(mCaCertBrowse, 1, 3);
	layout->addWidget(mUserCertBrowse, 3, 3);
#endif

	layout->addWidget(new QLabel(tr("Key name<sup>*</sup>")), 4, 0);
	layout->addWidget(mKey, 4, 1, 1, 3);
	layout->addWidget(mKeyBrowse, 5, 3);
	layout->setColumnStretch(1, 1);

	return box;
}
