/*****************************************************************************
 *
 *  softwareupdate.cpp -- Check and download software update.
 *
 *  Copyright (C) 2010 Starbuck <starbuck@labdv.com>
 *  All rights reserved.
 *
 *  This file is part of the Main module of the DVDx 4 application.
 *
 *  GNU Lesser General Public License Usage
 *  This file may be used under the terms of the GNU Lesser General
 *  Public License version 2.1 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.LGPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU Lesser General Public License version 2.1 requirements
 *  will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 *  GNU General Public License Usage
 *  Alternatively, this file may be used under the terms of the GNU
 *  General Public License version 3.0 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.GPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU General Public License version 3.0 requirements will be
 *  met: http://www.gnu.org/copyleft/gpl.html.
 *
 *****************************************************************************/

#include "../../src/main/macrosapp.h"
#include "softwareupdate.h"
#include <QByteArray>
#include <QDebug>
#include <QDesktopServices>
#include <QProcess>
#include <QRegExp>

#ifdef WIN32
#include "../../tools/buildnumber/buildnumberwin32.h"
#elif defined(Q_OS_MAC)
#include "../../tools/buildnumber/buildnumbermacx.h"
#else
#include "../../tools/buildnumber/buildnumberlinux.h"
#endif

SoftwareUpdate::SoftwareUpdate(QString *serverResponse, QString *whatYouGet, 
	QString *openEditionUrl, QString *smartEditionUrl, QObject *parent)
	: QObject(parent)
{
	m_reply = 0;
	m_serverResponse = serverResponse;
	m_openEditionUrl = openEditionUrl;
	m_smartEditionUrl = smartEditionUrl;
	m_whatYouGet = whatYouGet;

#ifdef WIN32
	m_appPlatform = "win32";
	QString systemCommand = "cmd.exe";
	QStringList systemArguments = QStringList() << "/c" << "ver";
#elif defined(Q_OS_MAC)
	m_appPlatform = "macx";
	QString systemCommand = "uname";
	QStringList systemArguments = QStringList() << "-spr";
#else
	m_appPlatform = "linux";
	QString systemCommand = "uname";
	QStringList systemArguments = QStringList() << "-spro";
#endif
	QProcess process;
	process.start(systemCommand.toLatin1(), systemArguments);
	if (process.waitForStarted(2000)) 
		if (process.waitForFinished(2000)) 
			m_appSystem = process.readAll();
	process.close();
#ifdef WIN32
	m_appSystem.replace(QString("\r\n"), QString());  // remove useless blank lines
#endif
	m_appSystem = m_appSystem.toLatin1();
	m_appVersion = APPVERSION_STR;
	m_appBuild = BUILDNUMBER_STR;
}

SoftwareUpdate::~SoftwareUpdate()
{
	if (m_reply) m_reply->deleteLater();
}

void SoftwareUpdate::checkUpdate()
{
	if (m_reply && m_reply->isRunning()) return;  // once at a time

	QNetworkAccessManager *accessManager = new QNetworkAccessManager(this);
	QNetworkConfigurationManager configurationManager;
	accessManager->setConfiguration(configurationManager.defaultConfiguration());
	if (accessManager->networkAccessible() != QNetworkAccessManager::Accessible)
	{
		// sounds to tough, we try to connect and we'll get a further error if not accessible
		//emit checkUpdateFailed(tr("The Internet is not accessible"));
		//return;
	}

	QString dataToEncode =  QString("platform=%1&version=%2&build=%3&system=%4")
		.arg(m_appPlatform).arg(m_appVersion).arg(m_appBuild).arg(m_appSystem);
	
	QByteArray data = QUrl(dataToEncode).toEncoded();  // space aren't + so might be %20 so NOT LIKE HTML FORMS
	qDebug() << data;

	QNetworkRequest request;
	request.setUrl(QUrl("http://www.labdv.com/dvdx/update/request.php"));
	request.setRawHeader("Referer", QString("CheckUpdates").toLatin1());
	request.setRawHeader("User-Agent", QString("%1 %2").arg(APPNAME).arg(APPVERSION_STR).toLatin1());
	request.setRawHeader("Content-Type", QString("application/x-www-form-urlencoded").toLatin1());

	m_reply = accessManager->post( request, data );

	connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(checkUpdateError(QNetworkReply::NetworkError)));
	connect(m_reply, SIGNAL(finished()), this, SLOT(checkUpdateFinish()));
	connect(m_reply, SIGNAL(readyRead()), this, SLOT(checkUpdateRead()));

	emit checkUpdateStarted();
}

void SoftwareUpdate::checkUpdateError(QNetworkReply::NetworkError code)
{
	QString error;

	if (m_reply && m_reply->error())
	{
		error = m_reply->errorString();
	}
	else
	{
		error = tr("network error #%1").arg(code);
	}

	m_reply->deleteLater();
	m_reply = 0;
	emit checkUpdateFailed(error);
}

void SoftwareUpdate::checkUpdateFinish()
{
	if (m_reply && m_reply->error())
	{
		QString error = m_reply->errorString();

		m_reply->deleteLater();
		m_reply = 0;
		emit checkUpdateFailed(error);
	}
	else
	{
		m_reply->deleteLater();
		m_reply = 0;
		emit checkUpdateFinished();
	}
}

void SoftwareUpdate::checkUpdateRead()
{
	if (m_reply)
	{
		m_serverResponse->clear();
		m_openEditionUrl->clear();
		m_smartEditionUrl->clear();
		
		QByteArray response = m_reply->readAll();

		QRegExp rx;
		rx.setCaseSensitivity(Qt::CaseSensitive);
		rx.setMinimal(false);

		rx.setPattern("<RESPONSE>(.*)</RESPONSE>");
		rx.indexIn(response);
		if (rx.numCaptures() == 1) *m_serverResponse = rx.cap(1).trimmed();

		rx.setPattern("<OPENURL>(.*)</OPENURL>");
		rx.indexIn(response);
		if (rx.numCaptures() == 1) *m_openEditionUrl = rx.cap(1).trimmed();

		rx.setPattern("<SMARTURL>(.*)</SMARTURL>");
		rx.indexIn(response);
		if (rx.numCaptures() == 1) *m_smartEditionUrl = rx.cap(1).trimmed();

		rx.setPattern("<WHATYOUGET>(.*)</WHATYOUGET>");
		rx.indexIn(response);
		if (rx.numCaptures() == 1) *m_whatYouGet = rx.cap(1).trimmed();

		m_reply->deleteLater();
		m_reply = 0;
		emit checkUpdateSucceeded();
	}
	else
	{
		m_reply->deleteLater();
		m_reply = 0;
		emit checkUpdateFailed(tr("can't read network reply"));
	}
}
