#include "PSKlient.h"

// Inhalt der PSKlient Klasse aus PSKlient.h
// Konstruktor
PSKlient::PSKlient( const char *ip, int port )
    : LTSKlient( ip, port )
{}

// Destruktor
PSKlient::~PSKlient()
{}

// nicht constant
bool PSKlient::getDateiListe( int *systemAnzahl, Array< int > *dateiAnzahl, RCArray< Text > *systeme, RCArray< RCArray< Text > > *dateien )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\xB", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während GetDateiListe bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    *systemAnzahl = 0;
    int län = 0;
    k->getNachricht( (char *)& län, 4 );
    while( län )
    { // System Sleife
        char *txt = new char[ län + 1 ];
        txt[ län ] = 0;
        k->getNachricht( txt, län );
        systeme->set( new Text( txt ), *systemAnzahl );
        delete[] txt;
        dateien->set( new RCArray< Text >(), *systemAnzahl );
        int dAnzahl = 0;
        k->getNachricht( (char *)& län, 4 );
        while( län )
        { // Datei Schleife
            char *txt = new char[ län + 1 ];
            txt[ län ] = 0;
            k->getNachricht( txt, län );
            dateien->z( *systemAnzahl )->set( new Text( txt ), dAnzahl );
            delete[] txt;
            dAnzahl++;
            k->getNachricht( (char *)& län, 4 );
        }
        dateiAnzahl->set( dAnzahl, *systemAnzahl );
        ( *systemAnzahl )++;
        k->getNachricht( (char *)& län, 4 );
    }
    unlock();
    return 1;
}

bool PSKlient::updateFertig()
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\xC", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während UpdateFertig bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

bool PSKlient::updateStarten( int dateiGruppeId )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\xD", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während UpdateStarten bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    k->sende( (char *)& dateiGruppeId, 4 );
    k->getNachricht( (char *)& res, 1 );
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während UpdateStarten bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

bool PSKlient::getFileGroupInfoList( Array< FileGroupInfo * > *list )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\x10", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 1 )
    {
        int anz = 0;
        k->getNachricht( (char *)& anz, 4 );
        for( int i = 0; i < anz; i++ )
        {
            FileGroupInfo *info = new FileGroupInfo();
            k->getNachricht( (char *)& info->id, 4 );
            unsigned char len = 0;
            k->getNachricht( (char *)& len, 1 );
            info->name.fillText( ' ', len );
            k->getNachricht( info->name, len );
            k->getNachricht( (char *)& len, 1 );
            info->status.fillText( ' ', len );
            k->getNachricht( info->status, len );
            unsigned short l = 0;
            k->getNachricht( (char *)& l, 2 );
            info->path.fillText( ' ', l );
            k->getNachricht( info->path, l );
            k->getNachricht( (char *)& info->version, 4 );
            list->add( info );
        }
    }
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während getFileGroupInfoList bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

bool PSKlient::getSystemInfoList( RCArray< ReferenceCounting< std::pair< int, Text > > > *list )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\x11", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 1 )
    {
        int anz = 0;
        k->getNachricht( (char *)& anz, 4 );
        for( int i = 0; i < anz; i++ )
        {
            ReferenceCounting< std::pair< int, Text > > *obj = new ReferenceCounting< std::pair< int, Text > >();
            k->getNachricht( (char *)& obj->first, 4 );
            unsigned char len = 0;
            k->getNachricht( (char *)& len, 1 );
            obj->second.fillText( ' ', len );
            k->getNachricht( obj->second, len );
            list->add( obj );
        }
    }
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während getSystemInfoList bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

bool PSKlient::getFileInfoList( int system, int group, RCArray< ReferenceCounting< FileInfo > > *list )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\x12", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 1 )
    {
        k->sende( (char *)& system, 4 );
        k->sende( (char *)& group, 4 );
        int anz = 0;
        k->getNachricht( (char *)& anz, 4 );
        for( int i = 0; i < anz; i++ )
        {
            ReferenceCounting< FileInfo > *obj = new ReferenceCounting< FileInfo >();
            k->getNachricht( (char *)& obj->id, 4 );
            unsigned short len = 0;
            k->getNachricht( (char *)& len, 2 );
            obj->path.fillText( ' ', len );
            k->getNachricht( obj->path, len );
            k->getNachricht( (char *)& obj->version, 4 );
            unsigned char l = 0;
            k->getNachricht( (char *)& l, 1 );
            obj->time.fillText( ' ', l );
            k->getNachricht( obj->time, l );
            list->add( obj );
        }
    }
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während getSystemInfoList bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

bool PSKlient::getFileVersion( char *path, int system, int group, int *version )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\x13", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 1 )
    {
        unsigned short len = textLength( path );
        k->sende( (char *)& len, 2 );
        k->sende( path, len );
        k->sende( (char *)& group, 4 );
        k->sende( (char *)& system, 4 );
        k->getNachricht( (char *)version, 4 );
    }
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während getSystemInfoList bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

bool PSKlient::updateFile( const char *pfad, char status, Zeit *zLetzteÄnderung, int system, int gruppe )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\x14", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 1 )
    {
        unsigned short len = textLength( pfad );
        k->sende( (char *)& len, 2 );
        k->sende( pfad, len );
        k->sende( &status, 1 );
        if( zLetzteÄnderung )
        {
            Text *time = zLetzteÄnderung->getZeit( "y-m-d h:i:s" );
            unsigned char l = (unsigned char)time->getLength();
            k->sende( (char *)& l, 1 );
            k->sende( time->getText(), l );
            time->release();
        }
        else
            k->sende( (char *)"\x0", 1 );
        k->sende( (char *)& system, 4 );
        k->sende( (char *)& gruppe, 4 );
        k->getNachricht( (char *)& res, 1 );
    }
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während getSystemInfoList bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

bool PSKlient::dateiGruppeUpdate( int gruppe )
{
    if( !verbunden )
        verbinden();
    if( !verbunden )
        return 0;
    lock();
    k->sende( "\x15", 1 );
    unsigned char res = 0;
    k->getNachricht( (char *)& res, 1 );
    if( res == 1 )
    {
        k->sende( (char *)& gruppe, 4 );
        k->getNachricht( (char *)& res, 1 );
    }
    if( res == 3 )
    {
        k->getNachricht( (char *)& res, 1 );
        char *txt = new char[ res + 1 ];
        k->getNachricht( txt, res );
        txt[ res ] = 0;
        fehler->setText( "Fehler während getSystemInfoList bei PatchServer.\nServer Rückgabe:" );
        fehler->append( txt );
        delete[] txt;
        unlock();
        return 0;
    }
    unlock();
    return 1;
}

void PSKlient::abbruch()
{
    if( verbunden )
        k->trenne();
    eingeloggt = 0;
    verbunden = 0;
}

// Reference Counting
LTSKlient *PSKlient::getThis()
{
    ref++;
    return this;
}

LTSKlient *PSKlient::release()
{
    ref--;
    if( !ref )
        delete this;
    return 0;
}