/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2006-2014  Georg Rudoy
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **********************************************************************/

#include "sslerrorsdialog.h"
#include <QDateTime>

namespace LeechCraft
{
namespace Azoth
{
namespace Acetamide
{
	SslErrorsDialog::SslErrorsDialog (QWidget *parent)
	: QDialog (parent)
	{
		Ui_.setupUi (this);
	}

	SslErrorsDialog::SslErrorsDialog (const QString& msg,
			const QList<QSslError>& errors,
			QWidget *parent)
	: QDialog (parent)
	{
		Ui_.setupUi (this);
		Update (msg, errors);
	}

	SslErrorsDialog::~SslErrorsDialog ()
	{
	}

	void SslErrorsDialog::Update (const QString& msg,
			const QList<QSslError>& errors)
	{
		Ui_.Description_->setText (msg);
		for (QList<QSslError>::const_iterator i = errors.begin (),
				end = errors.end (); i != end; ++i)
			PopulateTree (*i);
		Ui_.Errors_->expandAll ();
	}

	SslErrorsDialog::RememberChoice SslErrorsDialog::GetRememberChoice () const
	{
		if (Ui_.RememberNot_->isChecked ())
			return RCNot;
		else if (Ui_.RememberFile_->isChecked ())
			return RCFile;
		else
			return RCHost;
	}

	void SslErrorsDialog::PopulateTree (const QSslError& error)
	{
		const auto item = new QTreeWidgetItem (Ui_.Errors_,
				{ "Error:", error.errorString () });

		QSslCertificate cer = error.certificate ();
		if (cer.isNull ())
		{
			new QTreeWidgetItem (item,
					{
						tr ("Certificate"),
						tr ("(No certificate available for this error)")
					});
			return;
		}

		new QTreeWidgetItem (item,
				{
					tr ("Valid:"),
#if QT_VERSION < 0x050000
					cer.isValid () ?
#else
					!cer.isBlacklisted () ?
#endif
							tr ("yes") :
							tr ("no")
				});
		new QTreeWidgetItem (item, { tr ("Effective date:"), cer.effectiveDate ().toString () });
		new QTreeWidgetItem (item, { tr ("Expiry date:"), cer.expiryDate ().toString () });
		new QTreeWidgetItem (item, { tr ("Version:"), cer.version () });
		new QTreeWidgetItem (item, { tr ("Serial number:"), cer.serialNumber () });
		new QTreeWidgetItem (item, { tr ("MD5 digest:"), cer.digest (QCryptographicHash::Md5).toHex () });
		new QTreeWidgetItem (item, { tr ("SHA1 digest:"), cer.digest (QCryptographicHash::Sha1).toHex () });

		const auto issuer = new QTreeWidgetItem (item, { tr ("Issuer info") });
		const auto subject = new QTreeWidgetItem (item, { tr ("Subject info") });

#if QT_VERSION < 0x050000
		const auto addItem = [] (const QString& name, const QString& info, QTreeWidgetItem *parent)
		{
			if (!info.isEmpty ())
				new QTreeWidgetItem (parent, { name, info });
		};
		const auto addIssuerItem = [&addItem, &cer, issuer] (const QString& name, QSslCertificate::SubjectInfo key)
		{
			addItem (name, cer.issuerInfo (key), issuer);
		};
		const auto addSubjectItem = [&addItem, &cer, subject] (const QString& name, QSslCertificate::SubjectInfo key)
		{
			addItem (name, cer.subjectInfo (key), subject);
		};
#else
		const auto addItem = [] (const QString& name, const QStringList& infos, QTreeWidgetItem *parent)
		{
			if (!infos.isEmpty ())
				new QTreeWidgetItem (parent, { name, infos.join ("; ") });
		};
		const auto addIssuerItem = [&addItem, &cer, issuer] (const QString& name, QSslCertificate::SubjectInfo key)
		{
			addItem (name, cer.issuerInfo (key), issuer);
		};
		const auto addSubjectItem = [&addItem, &cer, subject] (const QString& name, QSslCertificate::SubjectInfo key)
		{
			addItem (name, cer.subjectInfo (key), subject);
		};
#endif

		QString tmpString;

		addIssuerItem (tr ("Organization:"), QSslCertificate::Organization);
		addIssuerItem (tr ("Common name:"), QSslCertificate::CommonName);
		addIssuerItem (tr ("Locality:"), QSslCertificate::LocalityName);
		addIssuerItem (tr ("Organizational unit name:"), QSslCertificate::OrganizationalUnitName);
		addIssuerItem (tr ("Country name:"), QSslCertificate::CountryName);
		addIssuerItem (tr ("State or province name:"), QSslCertificate::StateOrProvinceName);

		addSubjectItem (tr ("Organization:"), QSslCertificate::Organization);
		addSubjectItem (tr ("Common name:"), QSslCertificate::CommonName);
		addSubjectItem (tr ("Locality:"), QSslCertificate::LocalityName);
		addSubjectItem (tr ("Organizational unit name:"), QSslCertificate::OrganizationalUnitName);
		addSubjectItem (tr ("Country name:"), QSslCertificate::CountryName);
		addSubjectItem (tr ("State or province name:"), QSslCertificate::StateOrProvinceName);
	}
}
}
}
