/* ====================================================================
 * FTD4Linux Software License, Version 1.0
 *
 * Copyright (c) 2000-2004 The FTD4Linux Development Team.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        FTD4Linux Development Team (http://www.ftd4linux.2y.net/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "FTD" and "FTD4Linux" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact alguno@ftd4linux.2y.net.
 *
 * 5. Products derived from this software may not be called "FTD4Linux",
 *    nor may "FTD4Linux" appear in their name, without prior written
 *    permission of the FTD4Linux Development Team.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE FTD4LINUX DEVELOPMENT TEAM OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "ftd4linux.h"
#include "ftd_app_core.h"

/**
 * Stuurt een nieuw event naar de FTD servers.
 * Let erop dat ::ERROR_POST_MODERATED een succesvolle verzending inhoud!
 * Het versturen van een event bestaat uit vier delen.
 * In het eerste wordt de event verstuurd met de kernelementen, zoals titel en status.
 * Daarna wordt in deel twee de beschrijving gestuurd en in deel drie het repostbeleid.
 * Het laatste deel bevat de gegevens over mp3 bestanden.
 * Alleen delen die nodig zijn worden gedaan.
 *
 * @arg     event       Het te versturen event.
 * @arg     callback    Een callback-functie om de voortgang bij te houden.
 *
 * @return  Een fout-code die aangeeft of het verzenden succesvol was.
 */
FtdErrorCode
ftd_post_send(FtdEvent *event, void(*callback)(FtdSendState) )
{
    /*
     * sending a post consists of 4 passes. firstly
     * send the post with m=add with only the core elements
     * of the post like title / status e.d.
     * returned by the php scripts is the ID of the post
     * this will be used in the second and the third pass,
     * when we send the 'description' with m=upd and section=1
     * and in the third pass section=2 with sig=xxxx. In the
     * fourth the parameters are m=mp3 and the postid in s,
     * while a string is made from alle mp3-files separated by
     * |FTD| and put in str.
     */

    FtdList     *params = NULL;
    int          retval;
    FtdString   *uitvoer;
    FtdString   *groups = NULL;
    FtdString   *status = NULL;
    FtdString   *filtyp = NULL;
    FtdString   *nfiles = NULL;
    FtdString   *filsrt = NULL;
    FtdString   *parcnt = NULL;
    FtdString   *partyp = NULL;
    FtdString   *parblksize = NULL;
    FtdString   *cat    = NULL;
    FtdString   *scat   = NULL;
    FtdString   *id     = NULL;
    gboolean     moderated;
    FtdList     *tags = NULL;
    FtdList     *list = NULL;
    FtdString   *subcatTag = NULL;
    FtdString   *tagString = NULL;

    g_assert(core);
    g_assert(event);

    if( callback ) {
        callback(SEND_STATE_STARTING);
    }

    /* create cgi variables **/

    if (event->mp3Tracks) {
        // Stel de fileCount goed in omdat de Windows versie van FTD hier nogal van afhankelijk is (Bugzilla #63)
        event->fileStart = 1;
        event->aantalFiles = ftd_list_length(event->mp3Tracks);
    }

    groups = ftd_splitted_list_concat(event->groups);
    status = ftd_string_integer(event->status);
    filtyp = ftd_string_integer(event->fileType);
    nfiles = ftd_string_integer(event->aantalFiles);
    filsrt = ftd_string_integer(event->fileStart);
    parcnt = ftd_string_integer(event->aantalParFiles);
    partyp = ftd_string_integer(event->parType);
    if (event->parBlockSize > 0) {
        parblksize = ftd_string_integer(event->parBlockSize);
    }
    cat    = ftd_string_integer(event->cat);
    scat   = ftd_string_integer(event->sCat);
    subcatTag = ftd_string_append( ftd_string_new( "a" ), ftd_string_value( scat ) );
    list = event->tags;
    while( list ) {
        FtdString *tag = ftd_list_value( list );
        if( strcmp( ftd_string_value( tag ), ftd_string_value( subcatTag ) ) ) {
            tags = ftd_list_append( tags, tag );
        }
        list = ftd_list_next( list );
    }
    if( tags ) {
        tagString = ftd_splitted_list_concat( tags );
    } else {
        tagString = ftd_string_new( "" );
    }

    params = ftd_list_append(params, ftd_http_parameter_new("m", "add"));
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "t", ftd_string_value(event->title)));
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "s", ftd_string_value(status)));
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "g", ftd_string_value(groups)));
    if( event->fileName ) {
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "fstr", ftd_string_value(event->fileName)));
    }
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "ft", ftd_string_value(filtyp)));
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "fn", ftd_string_value(nfiles)));
    if (event->link) {
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "l", ftd_string_value(event->link)));
    }
    if (event->announcement) {
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "a", ftd_string_value(event->announcement)));
    }
    params = ftd_list_append(params, ftd_http_parameter_new(
                                    "fs", ftd_string_value(filsrt)));
    if (event->image) {
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "img", ftd_string_value(event->image)));
    }
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "pars", ftd_string_value(parcnt)));
    if (parblksize) {
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "bs", ftd_string_value(parblksize)));
    }
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "pt", ftd_string_value(partyp)));
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "c", ftd_string_value(cat)));
    params = ftd_list_append(params, ftd_http_parameter_new(
                                 "sc", ftd_string_value(scat)));
    params = ftd_list_append(params, ftd_http_parameter_new( "tags", ftd_string_value( tagString ) ) );
    if( event->extra_tag ) {
        params = ftd_list_append(params, ftd_http_parameter_new( "tag", ftd_string_value( event->extra_tag ) ) );
    }

    ftd_string_free(groups);
    ftd_string_free(status);
    ftd_string_free(filtyp);
    ftd_string_free(nfiles);
    ftd_string_free(filsrt);
    ftd_string_free(parcnt);
    ftd_string_free(partyp);
    ftd_string_free(cat);
    ftd_string_free(scat);
    ftd_string_free( tagString );
    ftd_string_free( subcatTag );
    ftd_list_free( tags );
    if( parblksize ) {
        ftd_string_free( parblksize );
    }

    if( callback ) {
        callback(SEND_STATE_FASE_1_CONNECT);
    }

    retval = ftd_http_curl_execute(FTD_URL_SEND_POST, params, TRUE, &uitvoer, TRUE, NULL, TRUE);
    ftd_http_parameter_free_all(params);

    if( callback ) {
        callback(SEND_STATE_FASE_1_DONE);
    }

    if (retval) {
        if( callback ) {
            callback( SEND_STATE_ERROR );
        }
        return retval;
    }

    // Server response kan er als volgt uit zien:
    // C        Post is gecancelled (gebruiker niet toegestaan om te posten)
    // 012345   Post is geplaatst, heeft FTD id 12345 meegekregen, maar
    //          de post moet nog door een mod beoordeeld worden
    // 112345   Post is geplaatst en direct doorgelaten (geauthenticeerd poster)

    if (ftd_string_value(uitvoer)[0] == 'C') {
        ftd_string_free(uitvoer);
        if( callback ) {
            callback( SEND_STATE_ERROR );
        }
        return ERROR_POST_CANCELLED;
    } else if (ftd_string_value(uitvoer)[0] == '0') {
        moderated = TRUE;
    } else if (ftd_string_value(uitvoer)[0] == '1') {
        moderated = FALSE;
    } else {
        ftd_string_free(uitvoer);
        if( callback ) {
            callback( SEND_STATE_ERROR );
        }
        return ERROR_PARSE;
    }

    if( callback ) {
        callback( SEND_STATE_FASE_1_ACCEPTED );
    }

    // +1 omdat we pas de data vanaf het 2e karakter nodig hebben
    event->postId = atoi(ftd_string_value(uitvoer) + 1);
    // FIXME: Het ziet er naar uit dat er voor geauthenticeerde posters nog iets achteraan komt, wat is onbekend

    ftd_string_free(uitvoer);

    // Fase 2, description doorsturen
    if (event->description) {
        id     = ftd_string_integer(event->postId);

        params = ftd_list_append(NULL, ftd_http_parameter_new(
                                     "section", "1"));
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "d", ftd_string_value(event->description)));
        params = ftd_list_append(params, ftd_http_parameter_new(
                                    "id", ftd_string_value(id)));
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "m", "upd"));
        ftd_string_free(id);

        if( callback ) {
            callback( SEND_STATE_FASE_2_CONNECT );
        }

        retval = ftd_http_curl_execute(FTD_URL_SEND_POST, params, TRUE, &uitvoer, TRUE, NULL, TRUE);
        ftd_http_parameter_free_all(params);

        if( callback ) {
            callback( SEND_STATE_FASE_2_DONE );
        }

        if (retval) {
            if( callback ) {
                callback( SEND_STATE_ERROR );
            }
            return retval;
        }

        if( callback ) {
            callback( SEND_STATE_FASE_2_ACCEPTED );
        }

        // We hebben als het goed is dezelfde server uitvoer als daarnet..parsen niet nodig
        ftd_string_free(uitvoer);
    }

    // Fase 3
    if (event->sig) {
        id     = ftd_string_integer(event->postId);

        params = ftd_list_append(NULL, ftd_http_parameter_new(
                                     "section", "2"));
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "sig", ftd_string_value(event->sig)));
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "id", ftd_string_value(id)));
        params = ftd_list_append(params, ftd_http_parameter_new(
                                     "m", "upd"));
        ftd_string_free(id);

        if( callback ) {
            callback( SEND_STATE_FASE_3_CONNECT );
        }

        retval = ftd_http_curl_execute(FTD_URL_SEND_POST, params, TRUE, &uitvoer, TRUE, NULL, TRUE);
        ftd_http_parameter_free_all(params);

        if( callback ) {
            callback( SEND_STATE_FASE_3_DONE );
        }

        if (retval) {
            if( callback ) {
                callback( SEND_STATE_ERROR );
            }
            return retval;
        }

        if( callback ) {
            callback( SEND_STATE_FASE_3_ACCEPTED );
        }

        // We hebben als het goed is dezelfde server uitvoer als daarnet..parsen niet nodig
        ftd_string_free(uitvoer);
    }

    // Fase 4
    if (event->mp3Tracks) {
        FtdList *mp3s;
        FtdString *res = NULL;

        id = ftd_string_integer(event->postId);
        mp3s = event->mp3Tracks;
        while( mp3s ) {
            FtdString *mp3 = ftd_list_value( mp3s );
            if( !res ) {
                res = ftd_string_new( ftd_string_value( mp3 ) );
            }
            else {
                res = ftd_string_append( ftd_string_append( res, "|FTD|" ), ftd_string_value( mp3 ) );
            }
            mp3s = ftd_list_next( mp3s );
        }

        // Vraag mij niet waarom, maar bij mp3 wordt s als id gezien
        params = ftd_list_append(NULL, ftd_http_parameter_new( "s", ftd_string_value(id) ) );
        params = ftd_list_append(params, ftd_http_parameter_new( "m", "mp3" ) );
        params = ftd_list_append(params, ftd_http_parameter_new( "str", ftd_string_value(res) ) );
        ftd_string_free(id);
        ftd_string_free( res );

        if( callback ) {
            callback( SEND_STATE_FASE_4_CONNECT );
        }
        retval = ftd_http_curl_execute(FTD_URL_SEND_POST, params, TRUE, &uitvoer, TRUE, NULL, TRUE);
        ftd_http_parameter_free_all(params);

        if( callback ) {
            callback( SEND_STATE_FASE_4_DONE );
        }

        if (retval) {
            if( callback ) {
                callback( SEND_STATE_ERROR );
            }
            return retval;
        }

        if( callback ) {
            callback( SEND_STATE_FASE_4_ACCEPTED );
        }

        // We hebben als het goed is dezelfde server uitvoer als daarnet..parsen niet nodig
        ftd_string_free(uitvoer);
    }

    if (moderated) {
        if( callback ) {
            callback( SEND_STATE_DONE_MODERATED );
        }
        return ERROR_POST_MODERATED;
    } else {
        if( callback ) {
            callback( SEND_STATE_DONE );
        }
        return ERROR_NONE;
    }
}
