/*
 *  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 "VpnEditWindow.h"
#include "FileDialogWPR.h"

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

VpnEditWindow::VpnEditWindow(VpnItem *item, QWidget *parent): QDialog(parent), mVpnItem(item)
{
	setWindowTitle(tr("Connection setup"));
	setWindowIcon(QIcon(QString(":img/vpn_edit_22.png")));
	
	mCancel = new QPushButton(tr("Ca&ncel"));
	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
VpnEditWindow::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);
	}
}

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

void
VpnEditWindow::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
VpnEditWindow::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
VpnEditWindow::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
VpnEditWindow::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;
	}
	
	QDir confDir(QDir::current().path() + QString("/") + mVpnItem->confName());
	QFile conf;
	
	// Reading template part of configuration file.
	conf.setFileName(confDir.path() + QString("/conf"));
	conf.open(QIODevice::ReadOnly);
	QByteArray confTemplate = conf.readAll();
	conf.close();
	
	int confTemplatePos = confTemplate.indexOf("\n#\n# configuration template\n#\n\n");
	
	if (confTemplatePos) confTemplate.remove(0, confTemplatePos);
	else confTemplate.clear();
	
	// Delete previous configuration.
	confDir.remove(QString("conf"));
	confDir.remove(QString("ca.cert"));
	confDir.remove(QString("user.cert"));
	
	// Save configuration.
	conf.setFileName(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(confTemplate);
	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();
}

QWidget*
VpnEditWindow::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*
VpnEditWindow::createNameBox()
{
	QGroupBox *box = new QGroupBox(tr("VPN conncetion name"));
	QGridLayout *layout = new QGridLayout;
	
	mSTokenVpnName = new QLineEdit(mVpnItem->sTokenVpnName());
	
	layout->addWidget(new QLabel(tr("Connection name<sup>*</sup>")), 0, 0);
	layout->addWidget(mSTokenVpnName, 0, 1);
	layout->setColumnStretch(1, 1);
	
	box->setLayout(layout);
	
	return box;
}

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

QGroupBox*
VpnEditWindow::createCertsKeyBox()
{
	QGroupBox *box = new QGroupBox(tr("Certificates and key"));
	QGridLayout *layout = new QGridLayout;
	QFile file;
	
	mCaCertFileName = mVpnItem->confName() + QString("/ca");
	file.setFileName(mCaCertFileName);
	file.open(QIODevice::ReadOnly);
	mCaCertData = file.readAll();
	file.close();
	
	mUserCertFileName = mVpnItem->confName() + QString("/user");
	file.setFileName(mUserCertFileName);
	file.open(QIODevice::ReadOnly);
	mUserCertData = file.readAll();
	file.close();
	
	mCaCert = new QLineEdit(mCaCertFileName);
	mCaCertBrowse = new QPushButton(tr("Select"));
	connect(mCaCertBrowse, SIGNAL(clicked()), this, SLOT(caCertBrowseSlot()));
	mUserCert = new QLineEdit(mUserCertFileName);
	mUserCertBrowse = new QPushButton(tr("Select"));
	connect(mUserCertBrowse, SIGNAL(clicked()), this, SLOT(userCertBrowseSlot()));
#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
	
	mKey = new QLineEdit(mVpnItem->key());
	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);
	
	box->setLayout(layout);
	
	return box;
}
