#include "ShopServer.h"
#include <Klient.h>
#include <iostream>

// Inhalt der Updater Klasse aus Updater.h
// Konstruktor
Updater::Updater( ShopServer *shServ )
    : Thread()
{
    shs = shServ;
    beenden = 0;
    start();
}

// Destruktor
Updater::~Updater()
{
    beenden = 1;
    warteAufThread( 5000 );
    if( isRunning() )
        ende();
    shs->release();
}

// nicht constant
void Updater::thread()
{
    while( !beenden )
    {
        for( int i = 0; i < 60; i++ )
        {
            if( beenden )
                break;
            Sleep( 1000 );
        }
        if( beenden )
            break;
        int kId = shs->zDB()->getUpdateKarte( shs->getId() );
        if( kId )
        {
            Text updatePf = shs->zInit()->zWert( "ShopSeitenPfad" )->getText();
            updatePf += "/update";
            DateiRemove( updatePf );
            int port = 0;
            Text ip = "";
            if( !shs->zDB()->getEditorServerPortIp( kId, &port, &ip ) )
                continue;
            Klient *k = new Klient();
            unsigned char key[ 20 ] = { 55, 124, 19, 204, 23, 5, 59, 75, 247, 138, 119, 111, 57, 250, 206, 187, 165, 6, 247, 151 };
            k->setEmpfangKey( (char *)key, 20 );
            k->setSendeKey( (char *)key, 20 );
            char ret = 0;
            if( !k->verbinde( (unsigned short)port, ip ) )
            {
                k = (Klient *)k->release();
                std::cout << "ShS: Updater: Fehler beim Updaten von Karte " << kId << ".\n Verbindung zum Editorserver konnte nicht hergestellt werden.\n";
                continue;
            }
            k->sendeEncrypted( "\x8", 1 );
            k->getNachrichtEncrypted( &ret, 1 );
            if( ret == 1 )
            {
                k->sendeEncrypted( (char *)&kId, 4 );
                k->getNachrichtEncrypted( &ret, 1 );
                if( ret == 1 )
                {
                    int anz = 0;
                    k->getNachrichtEncrypted( (char *)&anz, 4 );
                    for( int i = 0; i < anz && !beenden; i++ )
                    {
                        unsigned char len = 0;
                        k->getNachrichtEncrypted( (char *)&len, 1 );
                        if( !len )
                            continue;
                        char *pfa = new char[ len + 1 ];
                        pfa[ (int)len ] = 0;
                        k->getNachrichtEncrypted( pfa, len );
                        __int64 size = 0;
                        k->getNachrichtEncrypted( (char *)&size, 8 );
                        char *buffer = new char[ 2048 ];
                        Text pfad = updatePf;
                        pfad += pfa;
                        delete[] pfa;
                        Datei d;
                        d.setDatei( pfad );
                        d.erstellen();
                        d.open( Datei::Style::schreiben );
                        while( size )
                        {
                            int l = size >= 2048 ? 2048 : (int)size;
                            k->getNachricht( buffer, l );
                            d.schreibe( buffer, l );
                            size -= l;
                        }
                        d.close();
                        delete[] buffer;
                    }
                    if( beenden )
                    {
                        k->sendeEncrypted( "\3", 1 );
                        k->getNachrichtEncrypted( &ret, 1 );
                        k->trenne();
                        k->release();
                        break;
                    }
                    Text neuPfad = shs->zInit()->zWert( "ShopSeitenPfad" )->getText();
                    neuPfad += "/karten/";
                    neuPfad += kId;
                    DateiRemove( neuPfad );
                    DateiUmbenennen( updatePf, neuPfad );
                }
            }
            if( ret == 3 )
            {
                unsigned char byte = 0;
                k->getNachrichtEncrypted( (char *)&byte, 1 );
                char *f = new char[ byte + 1 ];
                f[ (int)byte ] = 0;
                k->getNachrichtEncrypted( f, byte );
                std::cout << "ShS: Updater: Fehler beim Update von Karte " << kId << ".\n Meldung: " << f << "\n";
                delete[] f;
                k->sendeEncrypted( "\3", 1 );
                k->getNachrichtEncrypted( &ret, 1 );
                k->trenne();
                k->release();
                continue;
            }
            k->sendeEncrypted( "\3", 1 );
            k->getNachrichtEncrypted( &ret, 1 );
            k->trenne();
            k->release();
            shs->zDB()->endUpdateKarte( kId );
        }
    }
    run = 0;
}