/* ====================================================================
 * 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"

//FIXME: Een en ander hier lijkt ernstig achter te lopen. Volgens mij is deze module ernstig aan een update toe.

/**
 * Een event voor gebruik in MyFTD.
 *
 * @see	::FtdEvent
 */
typedef struct _ftd_myftd_event {
    int          post_id;           ///< Het FTD-nummer van het event.
    time_t       stamp;             ///< De timestamp dat het event geplaatst is.
    gboolean     can_edit;          ///< True indien de gebruiker dit event mag wijzingen.
    FtdString   *title;             ///< De titel van het event.
    FtdList     *groups;            ///< De lijst met ::FtdGroup pointers naar de nieuwsgroepen waarin dit gepost wordt.
    FtdString   *filename;          ///< De bestandsnaam voor het event.
    int          status;            ///< De status van het event.
    FtdString   *poster;            ///< De naam van de poster van het event.
    FtdString   *link;              ///< Een eventuele link voor het event.
    int          cat;               ///< De FTD-categorie waaronder het event valt.
    int          sCat;              ///< De FTD sub-categorie waaronder het event valt.
    time_t       updated;           ///< De timestamp dat het event het laatst gewijzigd is.
    int          kudos;             ///< Het aantal kudos dat het event verdiend heeft.
    int          forum;             ///< Aantal forum-reacties.
    int          reps;              ///< Aantal geposte parblocken.
    int          reqs;              ///< Aantal aangevraagde parblocken.
    int          rating;            ///< Rating van het event.
    int          mod;               ///< Deze vlag geeft de moderatie-status aan. @note De waarden van deze vlag zijn onbekend.
} FtdMyFTDEvent;

int          ftd_myftd_parse(FtdString *, FtdList **);
void         ftd_myftd_parse_event(xmlDocPtr, xmlNodePtr, FtdMyFTDEvent *);
xmlDocPtr    ftd_myftd_print(FtdList *);


/**
 * Leest de gegevens van een lijst MyFTD events uit een XML gecodeerde string.
 *
 * @arg     buffer          De XML gecodeerde string.
 * @arg     ret             Hier komt de nieuwe lijst met ::FtdMyFTDEvent pointers naar de gevonden gegevens in te staan.
 *
 * @return  0 indien dit succesvol was.
 */
int
ftd_myftd_parse(FtdString *buffer, FtdList **ret)
{
    xmlDocPtr        doc;
    xmlNodePtr       cur;
    FtdList         *list = NULL;

    g_assert(core);
    g_assert(buffer);

    doc = xmlParseMemory(ftd_string_value(buffer), ftd_string_length(buffer));
    cur = xmlDocGetRootElement(doc);
    if (cur == NULL) {
        fprintf(stderr,"ftd_group_parse(): empty document!\n");
        xmlFreeDoc(doc);
        *ret = NULL;
        return 1;
    }

    if (strcasecmp(cur->name, "MyFTD") != 0) {
        fprintf(stderr,"ftd_group_parse(): document of the wrong type, root node != Groups");
        xmlFreeDoc(doc);
        *ret = NULL;
        return 2;
    }

    cur = cur->xmlChildrenNode;
    if (!cur) {
        // Een warning is niet nodig hier
        xmlFreeDoc(doc);
        *ret = NULL;
        return 3;
    }

    while (cur) {
        if (!strcasecmp(cur->name, "Post")) {
            int id = ftd_xml_parse_int_attr(doc, cur, "ID");
            if (id > 0) {
                FtdMyFTDEvent *event = g_malloc0(sizeof(FtdMyFTDEvent));
                event->post_id = id;
                ftd_myftd_parse_event(doc, cur->xmlChildrenNode, event);
                list = ftd_list_append(list, event);
            }
        }
        cur = cur->next;
    }
    xmlFreeDoc(doc);

    *ret = list;

    return 0;
}

/**
 * Leest een MyFTD event uit een XML boom.
 *
 * @arg     doc         Het XML document waar het MyFTD event in staat.
 * @arg     cur         Een pointer naar het element in het document waar hte MyFTD event begint.
 * @arg     event       Hier komen de gegevens in te staan.
 */
void
ftd_myftd_parse_event(xmlDocPtr doc, xmlNodePtr cur, FtdMyFTDEvent *event)
{
    while(cur != NULL) {
        if (!strcasecmp(cur->name, "Stamp")) {
            event->stamp = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Edit")) {
            FtdString *res = ftd_xml_parse_string(doc, cur);
            if (!strcmp(ftd_string_value(res), "n")) {
                event->can_edit = FALSE;
            } else {
                event->can_edit = TRUE;
            }
            ftd_string_free(res);
        }
        if (!strcasecmp(cur->name, "Title")) {
            event->title = ftd_xml_parse_string(doc, cur);
        }
        if (!strcasecmp(cur->name, "Groups")) {
            FtdString *tmp = ftd_xml_parse_string(doc, cur);
            event->groups = ftd_splitted_list_split(ftd_string_value(tmp));
            ftd_string_free(tmp);
        }
        if (!strcasecmp(cur->name, "FName")) {
            event->filename = ftd_xml_parse_string(doc, cur);
        }
        if (!strcasecmp(cur->name, "Status")) {
            event->status = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Poster")) {
            event->poster = ftd_xml_parse_string(doc, cur);
        }
        if (!strcasecmp(cur->name, "Link")) {
            event->link = ftd_xml_parse_string(doc, cur);
        }
        if (!strcasecmp(cur->name, "Cat")) {
            event->cat = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "SCat")) {
            event->sCat = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Updated")) {
            event->updated = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Kudos")) {
            event->kudos = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Forum")) {
            event->forum = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Reps")) {
            event->reps = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Reqs")) {
            event->reqs = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Rating")) {
            event->rating = ftd_xml_parse_int(doc, cur);
        }
        if (!strcasecmp(cur->name, "Mod")) {
            event->mod = ftd_xml_parse_int(doc, cur);
        }
// FIXME: Komen hier ook nog tags aan te pas ?
        cur = cur->next;
    }

    return;
}

/**
 * Maakt een XML document van een lijst van MyFTD events.
 *
 * @arg     myftd_list      De lijst met ::FtdMyFTDEvent pointers naar MyFTD events die in het document moeten komen.
 *
 * @return  Het nieuwe XML document met de gegevens van de MyFTD events.
 */
xmlDocPtr
ftd_myftd_print(FtdList *myftd_list)
{
    xmlDocPtr doc;
    xmlNodePtr rootNode, eventNode;
    FtdList *list = myftd_list;

    doc = xmlNewDoc(BAD_CAST "1.0");
    rootNode = xmlNewNode(NULL, BAD_CAST "MyFTD");
    xmlDocSetRootElement(doc, rootNode);

    while (list) {
        FtdString *str;
        char *datum;
        FtdMyFTDEvent *event = ftd_list_value(list);

        eventNode = xmlNewNode(NULL, BAD_CAST "Post");
        xmlAddChild(rootNode, eventNode);

        str = ftd_string_integer(event->post_id);
        xmlNewTextChild(eventNode, NULL, "PostID", ftd_string_value(str));
        ftd_string_free(str);

        datum = ftd_string_date(event->stamp);
        xmlNewTextChild(eventNode, NULL, "Datum", datum);
        g_free(datum);

        str = ftd_string_integer(event->can_edit);
        xmlNewTextChild(eventNode, NULL, "CanEdit", ftd_string_value(str));
        ftd_string_free(str);

        xmlNewTextChild(eventNode, NULL, "Title", ftd_string_value(event->title));

        str = ftd_splitted_list_concat(event->groups);
        xmlNewTextChild(eventNode, NULL, "Groups", ftd_string_value(str));
        ftd_string_free(str);

        xmlNewTextChild(eventNode, NULL, "FName", ftd_string_value(event->filename));

        str = ftd_string_integer(event->status);
        xmlNewTextChild(eventNode, NULL, "Status", ftd_string_value(str));
        ftd_string_free(str);

        xmlNewTextChild(eventNode, NULL, "Poster", ftd_string_value(event->poster));
        xmlNewTextChild(eventNode, NULL, "Link", ftd_string_value(event->link));

        str = ftd_string_integer(event->cat);
        xmlNewTextChild(eventNode, NULL, "Cat", ftd_string_value(str));
        ftd_string_free(str);

        str = ftd_string_integer(event->sCat);
        xmlNewTextChild(eventNode, NULL, "SCat", ftd_string_value(str));
        ftd_string_free(str);

        datum = ftd_string_date(event->updated);
        xmlNewTextChild(eventNode, NULL, "Updated", datum);
        g_free(datum);

        str = ftd_string_integer(event->kudos);
        xmlNewTextChild(eventNode, NULL, "Kudos", ftd_string_value(str));
        ftd_string_free(str);

        str = ftd_string_integer(event->forum);
        xmlNewTextChild(eventNode, NULL, "Forum", ftd_string_value(str));
        ftd_string_free(str);

        str = ftd_string_integer(event->reps);
        xmlNewTextChild(eventNode, NULL, "Reps", ftd_string_value(str));
        ftd_string_free(str);

        str = ftd_string_integer(event->reqs);
        xmlNewTextChild(eventNode, NULL, "Reqs", ftd_string_value(str));
        ftd_string_free(str);

        str = ftd_string_integer(event->rating);
        xmlNewTextChild(eventNode, NULL, "Rating", ftd_string_value(str));
        ftd_string_free(str);

        str = ftd_string_integer(event->mod);
        xmlNewTextChild(eventNode, NULL, "Mod", ftd_string_value(str));
        ftd_string_free(str);

        list = ftd_list_next(list);
    }

    return doc;
}

FtdErrorCode
ftd_myftd_update(int postId, char **errmsg)
{
    FtdList *params = NULL;
    FtdString *uitvoer = NULL;
    FtdErrorCode retval;
    char *tmp = g_strdup_printf("%i", postId);

    params = ftd_list_append(params, ftd_http_parameter_new("mode", "update"));
    params = ftd_list_append(params, ftd_http_parameter_new("id", tmp));
    g_free(tmp);
    retval = ftd_http_curl_execute(FTD_URL_MYFTD, params, TRUE, &uitvoer, TRUE, NULL, FALSE);
    ftd_http_parameter_free_all(params);

    if (retval) {
        if (retval == ERROR_MSG) {
            *errmsg = g_strdup(ftd_string_value(uitvoer));
        } else {
            *errmsg = NULL;
        }
    }

    // FIXME: bekijk de reactie van de FTD server
#if 0
    g_print("ftd_myftd_update: reactie van server = %s\n", ftd_string_value(uitvoer));
#endif

    if (uitvoer) {
        ftd_string_free(uitvoer);
    }

    return retval;
}
