/*
*
*  $Id: comandoactualizaciones.cpp $
*  Ginkgo CADx Project
*
*  Copyright 2008-12 MetaEmotion S.L. All rights reserved.
*  http://ginkgo-cadx.com
*
*  This file is licensed under LGPL v3 license.
*  See License.txt for details
*
*/

//#define _GINKGO_TRACE
#include <sstream>
#include <api/internationalization/internationalization.h>

#include <wx/xml/xml.h>
#include <wx/msgdlg.h>
#include <wx/sstream.h>
#include <wx/url.h>
#include <wx/wxhttpengine/httpbuilder.h>
#include <main/controllers/configurationcontroller.h>

#include <api/globals.h>

#include <main/entorno.h>
#include <main/controllers/controladoreventos.h>
#include <main/controllers/controladorlog.h>
#include <eventos/updateavailable.h>

#include "comandoactualizaciones.h"

#define IDC_CHECK_UPDATES 112

GNC::ComandoComprobarActualizacionesParams::ComandoComprobarActualizacionesParams(const std::string& url, bool informar) :
		m_URL(url),
		m_Informar(informar) 
{
	m_pBuilder = new wxHTTPBuilder();
}

GNC::ComandoComprobarActualizacionesParams::~ComandoComprobarActualizacionesParams()
{
	delete m_pBuilder;
}

GNC::ComandoComprobarActualizaciones::ComandoComprobarActualizaciones(ComandoComprobarActualizacionesParams* pParams) :
		IComando(pParams, _Std("Check Updates")),
		m_pComprobarActualizacionesParams(pParams),
		m_Version(),
		m_Revision(0),
		m_Description(),
		m_URL()
{
	SetId(IDC_CHECK_UPDATES);
	CancelaA(IDC_CHECK_UPDATES);	
}

const std::string& GNC::ComandoComprobarActualizaciones::GetError() const
{
	return m_Error;
}

const std::string& GNC::ComandoComprobarActualizaciones::GetVersion() const
{
	return m_Version;
}

const std::string& GNC::ComandoComprobarActualizaciones::GetDescription() const
{
	return m_Description;
}

int GNC::ComandoComprobarActualizaciones::GetRevision() const
{
	return m_Revision;
}


void GNC::ComandoComprobarActualizaciones::Execute()
{
	std::string tarea(_Std("Checking program updates..."));
	NotificarProgreso(0.0, tarea);

	if (EstaAbortado()) {
		return;
	}

	try {
		wxHTTPBuilder& builder = *m_pComprobarActualizacionesParams->m_pBuilder;
		wxProxySettings settings;
		settings.ProxySettingsLoadGeneral();
		builder.SetProxySettings(settings);
		builder.InitContentTypes();

		wxInputStream* inputStream = builder.GetInputStream2(wxString::FromUTF8(m_pComprobarActualizacionesParams->m_URL.c_str()));

		if (builder.GetError() != wxPROTO_NOERR) {
			std::ostringstream os;
			os << builder.GetLastError().ToUTF8();
			os << ". URL = " << m_pComprobarActualizacionesParams->m_URL;
			m_Error  = os.str();
			return;
		}

		wxXmlDocument xml;
		xml.Load(*inputStream, wxT("UTF-8"));
		wxXmlNode* raiz = xml.GetRoot();
		if (raiz == NULL) {
			m_Error = "XML invalid";
			return;
		}
		if (raiz->GetName() == wxT("ginkgo")) {
			wxString propVal;
			
			for (wxXmlNode* nodo = raiz->GetChildren(); nodo != NULL; nodo = nodo->GetNext()) {
				
				if (nodo->GetName() == wxT("version")) {
					m_Version = std::string(nodo->GetNodeContent().Trim().ToUTF8());
				}
				else if (nodo->GetName() == wxT("revision")) {
					long val;
					if ( nodo->GetNodeContent().Trim().ToLong(&val) ) {
						if (val >= 0) {
							m_Revision = (int) val;
						}
					}
				}
				else if (nodo->GetName() == wxT("description")) {
					m_Description = std::string(nodo->GetNodeContent().Trim().ToUTF8());
				}
				else if (nodo->GetName() == wxT("url")) {
					m_URL = std::string(nodo->GetNodeContent().Trim().ToUTF8());
				}
			}
		}
		delete inputStream;

		if (m_URL.empty()) {
			m_Error = _Std("Not enough parameters found on XML");
			Abort();
			return;
		}

		//Sleep(3000);
	}
	catch (...)
	{
		m_Error = _Std("XML parsing internal error");
		Abort();
	}
	GTRACE("Saliendo comando ComprobarActualizaciones ");
}

void GNC::ComandoComprobarActualizaciones::Update()
{

	if (m_Error.size() > 0) {
		LOG_ERROR("Core/Update", m_Error);
		if (m_pComprobarActualizacionesParams->m_Informar) {
			wxMessageBox(_("Error checking application updates"), _("Ginkgo CADx updates"), wxICON_ERROR);
		}
		return;
	}

	if (EstaAbortado()) {
		return;
	}
	try {

		GNC::GCS::ControladorEventos::Instance()->ProcesarEvento(new GNC::GCS::Events::EventoUpdateAvailable(m_Version, m_Revision, m_Description, m_URL, m_pComprobarActualizacionesParams->m_Informar));
	}
	catch (...)
	{
		LOG_ERROR("CORE/Updates", _Std("Internal error checking updates"));
	}

}

void GNC::ComandoComprobarActualizaciones::OnAbort()
{
	m_pComprobarActualizacionesParams->m_pBuilder->Stop();
	m_pComprobarActualizacionesParams->m_pBuilder->Abort();
}

