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

// Inhalt der Updater Klasse aus Updater.h
// Konstruktor
Updater::Updater( KartenServer *kServ )
    : Thread()
{
    ks = kServ;
    beenden = 0;
    start();
}

// Destruktor
Updater::~Updater()
{
    beenden = 1;
    warteAufThread( 5000 );
    if( isRunning() )
        ende();
    ks->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 = ks->zDB()->getUpdateKarte( ks->getId() );
        if( kId )
        {
            Text updatePf = ks->zIni()->zWert( "KartenPfad" )->getText();
            updatePf += "/update";
            DateiRemove( updatePf );
            ks->karteUpdateStart( kId );
            int port = 0;
            Text ip = "";
            if( !ks->zDB()->getEditorServerPortIp( kId, &port, &ip ) )
            {
                ks->karteUpdateEnde();
                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 ) )
            {
                ks->karteUpdateEnde();
                k = k->release();
                std::cout << "KS: Updater: Fehler beim Updaten von Karte " << kId << ".\n Verbindung zum Editorserver konnte nicht hergestellt werden.\n";
                continue;
            }
            k->sendeEncrypted( "\x9", 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 )
                    {
                        ks->karteUpdateEnde();
                        k->sendeEncrypted( "\3", 1 );
                        k->getNachrichtEncrypted( &ret, 1 );
                        k->trenne();
                        k->release();
                        break;
                    }
                    Text neuPfad = ks->zIni()->zWert( "KartenPfad" )->getText();
                    neuPfad += "/";
                    neuPfad += kId;
                    DateiRemove( neuPfad );
                    DateiUmbenennen( updatePf, neuPfad );
                    Text stsPf = neuPfad.getText();
                    stsPf += "/server/sts.ltgd";
                    Datei sts;
                    sts.setDatei( stsPf );
                    sts.open( Datei::Style::lesen );
                    int sAnz = 0;
                    sts.lese( (char*)&sAnz, 4 );
                    sts.close();
                    ks->zDB()->setKarteSpielerAnzahl( kId, sAnz );
                }
            }
            if( ret == 3 )
            {
                ks->karteUpdateEnde();
                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 << "KS: 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();
            ks->zDB()->endUpdateKarte( kId );
            ks->karteUpdateEnde();
        }
    }
    run = 0;
}