#include "lib_http.h"

#include <wx/protocol/http.h>
#include <wx/socket.h>
#include <wx/wfstream.h>
#include <wx/filename.h>
#include <wx/ffile.h>
#include <wx/app.h>

#include <time.h>

/**
 * recupere un fichier sur le serveur HTTP Althea et recopie le contenu dans un fichier local
 * @param sServer serveur sur lequel recuperer le fichier
 * @param sRessource ressource a recuperer
 * @param sLocalFile nom du fichier a creer localement
 * @param iMaxRetries nombre maxi de tentatives de recuperation (1 par defaut)
 * @return true si tout s'est bien deroule, false en cas d'erreur
 */
bool getHttpRessource(const wxString & sServer, const wxString & sRessource, const wxString & sLocalFile, long iMaxRetries)
{
//    if(!wxApp::IsMainLoopRunning())
//        return false; // evite d'arriver a des cas d'utilisation du CPU a 100%

    int iNbRetries = 0;
    while(iNbRetries < iMaxRetries)
    {
        iNbRetries++;

        wxHTTP http;
        http.SetFlags(wxSOCKET_WAITALL | wxSOCKET_BLOCK);
        http.SetTimeout(5); // timeout de 5 secondes
        wxIPV4address serverAdr;
        http.SetHeader( wxT("User-Agent"), wxT("libhttp4wx") );
        bool bOk = serverAdr.Hostname(sServer);
        bOk = bOk && serverAdr.Service(80);
        bOk = bOk && (http.Connect(serverAdr,true) || http.Connect(serverAdr,true)); // on retente une 2eme connexion si la premiere echoue

        if(!bOk)
            continue;
        
        wxTheApp->Yield(true);

// TODO        http.SetHeader( wxT("Authorization"), wxT("blablabla") );
        wxString sRes(sRessource);
        sRes.Replace(wxT(" "),wxT("%20"));
        if(sRes.GetChar(0) != '/')
            sRes = wxT("/") + sRes;
        wxInputStream * input = http.GetInputStream(sRes);
        wxTheApp->Yield(true); // pour eviter les freeze
        bOk = (input != NULL) && (http.GetError() == wxPROTO_NOERR) && (http.GetResponse() == 200);
        if(bOk)
        {
//             size_t iFileSize = input->GetSize();
//             if(iFileSize >= 0xffffffff)
//                 iFileSize = 100 << 20; // 100Mo
             size_t iReaded = 0;
//             time_t iStartTime = time(NULL);
//             if(progressBar != NULL)
//             {
//                 progressBar->setRange(iFileSize);
//                 progressBar->setValue(iReaded);
//                 progressBar->setText(UTF82WX("Connexion ..."));
//             }

            wxFFileOutputStream output(sLocalFile,wxT("wb"));
            if(!output.Ok())
                bOk = false;

            unsigned char buffer[65536];

//            time_t iLastTime = iStartTime;
            while(bOk && !input->Eof())
            {
                input->Read(buffer,65536);
                size_t iBufSize = input->LastRead();
                if(iBufSize > 0)
                {
                    output.Write(buffer,iBufSize);
                    if(output.LastWrite() != iBufSize)
                    {
                        bOk = false;
                        break;
                    }
                    iReaded += iBufSize;

/*                    if(progressBar != NULL)
                    {
                        progressBar->setValue(iReaded);
                        time_t iCurrentTime = time(NULL);
                        if(iCurrentTime > iLastTime)
                        {
                            progressBar->setText(wxString::Format(UTF82WX("    %d Ko/sec    "), iReaded / 1024 / (iCurrentTime - iStartTime)));
                            iLastTime = iCurrentTime;
                        }
                    }*/
                }
                wxTheApp->Yield(true); // pour eviter les freeze
            }

            output.Close();
        }

        if(input != NULL)
            delete input;
        http.Close();

        if(bOk)
            return true;
    }
    return false;
}
