/* ====================================================================
 * 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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "ftd4linux.h"
#include "ftd_app_core.h"
#include "ftd_file.h"
#include "ftd_config.h"
#include "ftd_define.h"
#include "ftd_groups.h"

/**
 * Initialiseert de configuratue van FTD4linux.
 * Deze functie wordt aangeroepen vanuit ::ftd_config_load.
 */
void
ftd_config_init(void)
{
    g_assert(core);

    core->config                              = g_malloc0(sizeof(FtdConfig));

    core->config->firstTime                   = TRUE;    /* Ga er standaard van uit dat dit de eerste keer is dat FTD wordt opgestart */
    core->config->username                    = NULL;
    core->config->password                    = NULL;
    core->config->proxyHost                   = NULL;
    core->config->proxyPort                   = NULL;
    core->config->proxyUser                   = NULL;
    core->config->proxyPassword               = NULL;
    core->config->watchlist                   = NULL;
    core->config->badwords                    = NULL;
#ifndef BUILTIN_PLUGIN
    core->config->authPlugin                  = NULL;
#endif
    core->config->htmlRenderer                = ftd_string_new("");
    core->config->lastCheck                   = 0;
    core->config->prevCheck                   = 0;
    core->config->ledenCount                  = 0;
    core->config->numUsersOnline              = ftd_string_new("Onbekend");
    core->config->updatenBijOpstarten         = TRUE;
    core->config->toonInfoBijEenZoekresultaat = TRUE;
    core->config->startMaximized              = TRUE;
    core->config->toonStatusBijLaden          = TRUE;
    core->config->toonCategoriseerdeLijstBijKnopNieuw = TRUE;
    core->config->verwijderPostsNaXDagen      = 1;
    core->config->trayIcon                    = TRUE;
    core->config->toonGUIGroupFilter          = FALSE;  // Vanaf FTD 3.7 staat deze niet standaard meer aan
    core->config->groupFilter                 = FALSE;
    core->config->groupFilterList             = NULL;
    core->config->gebruikFontFamily           = TRUE;
    core->config->recursiveUpdate             = FALSE;
    core->config->geenTabbedBrowsing          = FALSE;
    core->config->watcher                     = NULL;
    core->config->toonWatcherNotifications    = TRUE;
    core->config->openPostinfoOpAchtergrond   = TRUE;
    core->config->ircNickname                 = NULL;   // NULL geeft aan dat de nickname hetzelfde is als de FTD username
    core->config->ircAltNickname              = ftd_string_new("");
    core->config->toonIRCClient               = TRUE;
    core->config->ratingScale                 = 100;
    core->config->statusList                  = NULL;
}

/**
 * Ruimt de configuratie op.
 * Deze functie wordt aangeroepen vanuit ::ftd_app_core_cleanup.
 */
void
ftd_config_free(void)
{
    g_assert(core);
    g_assert(core->config);

    /* let op dat we hier if (conditie) { actie; } blokken MOETEN
     * gebruiken, anders gaat glib assertion errors geven */
    if (core->config->username != NULL) {
        ftd_string_free(core->config->username);
    }

    if (core->config->password) {
        ftd_string_free(core->config->password);
    }

    if (core->config->proxyHost) {
        ftd_string_free(core->config->proxyHost);
    }

    if (core->config->proxyPort) {
        ftd_string_free(core->config->proxyPort);
    }

    if (core->config->proxyUser) {
        ftd_string_free(core->config->proxyUser);
    }

    if (core->config->proxyPassword) {
        ftd_string_free(core->config->proxyPassword);
    }

    if( core->config->numUsersOnline ) {
        ftd_string_free( core->config->numUsersOnline );
    }

    if (core->config->watchlist) {
        FtdList *list = core->config->watchlist;

        while (list) {
            FtdString *watchlist = ftd_list_value(list);
            ftd_string_free(watchlist);
            list = ftd_list_next(list);
        }

        ftd_list_free(core->config->watchlist);
    }

    if (core->config->watcher) {
        FtdList *list = core->config->watcher;

        while (list) {
            FtdString *zoekterm = ftd_list_value(list);
            ftd_string_free(zoekterm);
            list = ftd_list_next(list);
        }

        ftd_list_free(core->config->watcher);
    }

    if (core->config->badwords) {
        FtdList *list = core->config->badwords;

        while (list) {
            FtdString *badword = ftd_list_value(list);
            ftd_string_free(badword);
            list = ftd_list_next(list);
        }

        ftd_list_free(core->config->badwords);
    }

    if (core->config->groupFilterList) {
        ftd_splitted_list_free(&core->config->groupFilterList);
    }

#ifndef BUILTIN_PLUGIN
    if (core->config->authPlugin) {
        ftd_string_free(core->config->authPlugin);
    }
#endif

    if (core->config->htmlRenderer) {
        ftd_string_free(core->config->htmlRenderer);
    }

    if (core->config->ircNickname) {
        ftd_string_free(core->config->ircNickname);
    }

    if (core->config->ircAltNickname) {
        ftd_string_free(core->config->ircAltNickname);
    }

    if (core->config->statusList) {
        ftd_list_free(core->config->statusList);
    }

    /* Alle dynamisch gealloceerde velden uit de struct FtdConfig zijn
    weer vrijgegeven, geef de hoofd-struct dan ook maar vrij */
    g_free(core->config);
    core->config = NULL;
}

/**
 * Laadt de configuratie van FTD4linux.
 * Deze functie wordt aangeroepen vanuit ::ftd_app_core_init.
 */
void
ftd_config_load(void)
{
    FILE *file;
    char *line;
    char buffer[1024];
    char **parts;
    char *volledigeFilename;

    g_assert(core);

    // Voorkom memory leak
    if (core->config) {
        ftd_config_free();
    }
    ftd_config_init();

    g_assert(core->config);

    volledigeFilename = ftd_file_parse_cache_filename(CONFIG_FILE, FALSE);
    file = fopen(volledigeFilename, "r");

    if (!file) {
        g_warning("ftd_config_load(): cannot load configfile %s: %s", volledigeFilename, strerror(errno));
        g_free (volledigeFilename);
        return;
    }

    g_free (volledigeFilename);

    while ((line = fgets(buffer, 1024, file)) != NULL) {
        parts = g_strsplit(line, "=", 2);
        if (parts && parts[0] && parts[1]) { /* empty lines are allowed */
            if (strcmp(parts[0], "username") == 0) {
                core->config->username = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
            } else if (strcmp(parts[0], "password") == 0) {
                core->config->password = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
            } else if (strcmp(parts[0], "proxyHost") == 0) {
                core->config->proxyHost = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
            } else if (strcmp(parts[0], "proxyPort") == 0) {
                core->config->proxyPort = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
            } else if (strcmp(parts[0], "proxyUser") == 0) {
                core->config->proxyUser = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
            } else if (strcmp(parts[0], "proxyPassword") == 0) {
                core->config->proxyPassword = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
            } else if (strcmp(parts[0], "lastCheck") == 0) {
                core->config->lastCheck = atol(parts[1]);
            } else if (strcmp(parts[0], "prevCheck") == 0) {
                core->config->prevCheck = atol(parts[1]);
            } else if (strcmp(parts[0], "ledenCount") == 0) {
                core->config->ledenCount = atol(parts[1]);
            } else if (strcmp(parts[0], "usersOnline") == 0) {
                core->config->numUsersOnline = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
            } else if (strcmp(parts[0], "watchlist") == 0) {
                core->config->watchlist = ftd_list_append(core->config->watchlist, ftd_string_new(g_strstrip(parts[1])));
            } else if (strcmp(parts[0], "watcher") == 0) {
                core->config->watcher = ftd_list_append(core->config->watcher, ftd_string_new(g_strstrip(parts[1])));
            } else if (strcmp(parts[0], "badword") == 0) {
                core->config->badwords = ftd_list_append(core->config->badwords, ftd_string_new(g_strstrip(parts[1])));
#ifndef BUILTIN_PLUGIN
            } else if (strcmp(parts[0], "authPlugin") == 0) {
                core->config->authPlugin = strlen(g_strstrip(parts[1])) > 0 ? ftd_string_new(g_strstrip(parts[1])) : NULL;
#endif
            } else if (strcmp(parts[0], "htmlRenderer") == 0) {
                core->config->htmlRenderer = ftd_string_new(g_strstrip(parts[1]));
            } else if (strcmp(parts[0], "updatenBijOpstarten") == 0) {
                core->config->updatenBijOpstarten = atoi(parts[1]);
            } else if (strcmp(parts[0], "toonInfoBijEenZoekresultaat") == 0) {
                core->config->toonInfoBijEenZoekresultaat = atoi(parts[1]);
            } else if (strcmp(parts[0], "startMaximized") == 0) {
                core->config->startMaximized = atoi(parts[1]);
            } else if (strcmp(parts[0], "toonStatusBijLaden") == 0) {
                core->config->toonStatusBijLaden = atoi(parts[1]);
            } else if (strcmp(parts[0], "toonCategoriseerdeLijstBijKnopNieuw") == 0) {
                core->config->toonCategoriseerdeLijstBijKnopNieuw = atoi(parts[1]);
            } else if (strcmp(parts[0], "verwijderPostsNaXDagen") == 0) {
                core->config->verwijderPostsNaXDagen = atoi(parts[1]);
            } else if (strncmp(parts[0], "#", 1) == 0) {
                // commentaar...negeren
            } else if (strcmp(parts[0], "trayIcon") == 0) {
                core->config->trayIcon = atoi(parts[1]);
            } else if (strcmp(parts[0], "toonGUIGroupFilter") == 0) {
                core->config->toonGUIGroupFilter = atoi(parts[1]);
            } else if (strcmp(parts[0], "groupFilter") == 0) {
                core->config->groupFilter = atoi(parts[1]);
            } else if (strcmp(parts[0], "groupFilterList") == 0) {
                core->config->groupFilterList = ftd_splitted_list_split(g_strstrip(parts[1]));
            } else if (strcmp(parts[0], "gebruikFontFamily") == 0) {
                core->config->gebruikFontFamily = atoi(parts[1]);
            } else if (strcmp(parts[0], "recursiveUpdate") == 0) {
                core->config->recursiveUpdate = atoi(parts[1]);
            } else if (strcmp(parts[0], "geenTabbedBrowsing") == 0) {
                core->config->geenTabbedBrowsing = atoi(parts[1]);
            } else if (strcmp(parts[0], "toonWatcherNotifications") == 0) {
                core->config->toonWatcherNotifications = atoi(parts[1]);
            } else if (strcmp(parts[0], "openPostinfoOpAchtergrond") == 0) {
                core->config->openPostinfoOpAchtergrond = atoi(parts[1]);
            } else if (strcmp(parts[0], "ircNickname") == 0) {
                core->config->ircNickname = ftd_string_new(g_strstrip(parts[1]));
            } else if (strcmp(parts[0], "ircAltNickname") == 0) {
                core->config->ircAltNickname = ftd_string_new(g_strstrip(parts[1]));
            } else if (strcmp(parts[0], "toonIRCClient") == 0) {
                core->config->toonIRCClient = atoi(parts[1]);
            } else if (strcmp(parts[0], "ratingScale") == 0) {
                core->config->ratingScale = atoi(parts[1]);
            } else if (strcmp(parts[0], "statusFilter") == 0) {
                core->config->statusList = ftd_list_append(core->config->statusList, GINT_TO_POINTER(atoi(parts[1])));
            } else {
                g_warning("ftd_config_load(): unknown config option : %s\n", parts[0]);
            }
        }
        g_strfreev(parts);
    }

    /* Kijk of de username en password zijn ingevuld */
    if (    core->config->username && ftd_string_length(core->config->username) > 0 &&
            core->config->password && ftd_string_length(core->config->password) > 0) {
        /* Username en pass zijn ingevuld (not NULL) dus het hoofdprogramma mag gewoon gestart worden */
        core->config->firstTime = FALSE;
    }

    fclose(file);
}

/**
 * Slaat de configuratie van FTD4linux op.
 * Deze functie wordt aangeroepen vanuit ::ftd_app_core_cleanup.
 */
void
ftd_config_save(void)
{
    FILE *file;
    FtdList *list;
    char *volledigeFilename;
    FtdString *str;

    g_assert(core);
    g_assert(core->config);

    volledigeFilename = ftd_file_parse_cache_filename(CONFIG_FILE, FALSE);

    file = fopen(volledigeFilename, "w");

    g_free (volledigeFilename);

    if (!file) {
        g_warning("ftd_config_save(): cannot open save config : %s", strerror(errno));
        return;
    }

    if (core->config->username) {
        fprintf(file, "username=%s\n", ftd_string_value(core->config->username));
    }
    if (core->config->password) {
        fprintf(file, "password=%s\n", ftd_string_value(core->config->password));
    }
    if (core->config->proxyHost) {
        fprintf(file, "proxyHost=%s\n", ftd_string_value(core->config->proxyHost));
    }
    if (core->config->proxyPort) {
        fprintf(file, "proxyPort=%s\n", ftd_string_value(core->config->proxyPort));
    }
    if (core->config->proxyUser) {
        fprintf(file, "proxyUser=%s\n", ftd_string_value(core->config->proxyUser));
    }
    if (core->config->proxyPassword) {
        fprintf(file, "proxyPassword=%s\n", ftd_string_value(core->config->proxyPassword));
    }
#ifndef BUILTIN_PLUGIN
    if (core->config->authPlugin) {
        fprintf(file, "authPlugin=%s\n", ftd_string_value(core->config->authPlugin));
    }
#endif

    fprintf(file, "htmlRenderer=%s\n", ftd_string_value(core->config->htmlRenderer));
    fprintf(file, "lastCheck=%d\n", (unsigned int) core->config->lastCheck);
    fprintf(file, "prevCheck=%d\n", (unsigned int) core->config->prevCheck);
    fprintf(file, "ledenCount=%d\n", core->config->ledenCount);
    fprintf(file, "usersOnline=%s\n", ftd_string_value(core->config->numUsersOnline));
    fprintf(file, "updatenBijOpstarten=%i\n", core->config->updatenBijOpstarten);
    fprintf(file, "toonInfoBijEenZoekresultaat=%i\n", core->config->toonInfoBijEenZoekresultaat);
    fprintf(file, "startMaximized=%i\n", core->config->startMaximized);
    fprintf(file, "toonStatusBijLaden=%i\n", core->config->toonStatusBijLaden);
    fprintf(file, "toonCategoriseerdeLijstBijKnopNieuw=%i\n", core->config->toonCategoriseerdeLijstBijKnopNieuw);
    fprintf(file, "verwijderPostsNaXDagen=%i\n", core->config->verwijderPostsNaXDagen);
    fprintf(file, "trayIcon=%i\n", core->config->trayIcon);
    fprintf(file, "gebruikFontFamily=%i\n", core->config->gebruikFontFamily);
    fprintf(file, "toonGUIGroupFilter=%i\n", core->config->toonGUIGroupFilter);
    fprintf(file, "recursiveUpdate=%i\n", core->config->recursiveUpdate);
    fprintf(file, "geenTabbedBrowsing=%i\n", core->config->geenTabbedBrowsing);
    fprintf(file, "toonWatcherNotifications=%i\n", core->config->toonWatcherNotifications);
    fprintf(file, "openPostinfoOpAchtergrond=%i\n", core->config->openPostinfoOpAchtergrond);
    fprintf(file, "ratingScale=%i\n", core->config->ratingScale);
    fprintf(file, "toonIRCClient=%i\n", core->config->toonIRCClient);
    fprintf(file, "ircAltNickname=%s\n", ftd_string_value(core->config->ircAltNickname));

    if (core->config->ircNickname) {
        fprintf(file, "ircNickname=%s\n", ftd_string_value(core->config->ircNickname));
    }

    fprintf(file, "groupFilter=%i\n", core->config->groupFilter);
    str = ftd_splitted_list_concat(core->config->groupFilterList);
    fprintf(file, "groupFilterList=%s\n", ftd_string_value(str));
    ftd_string_free(str);

    list = core->config->watchlist;

    while (list) {
        FtdString *watchlist = ftd_list_value(list);
        fprintf(file, "watchlist=%s\n", ftd_string_value(watchlist));
        list = ftd_list_next(list);
    }

    list = core->config->watcher;

    while (list) {
        FtdString *zoekterm = ftd_list_value(list);
        fprintf(file, "watcher=%s\n", ftd_string_value(zoekterm));
        list = ftd_list_next(list);
    }

    list = core->config->badwords;

    while (list) {
        FtdString *badword = ftd_list_value(list);
        fprintf(file, "badword=%s\n", ftd_string_value(badword));
        list = ftd_list_next(list);
    }

    list = core->config->statusList;

    while (list) {
        int status = GPOINTER_TO_INT(ftd_list_value(list));
        fprintf(file, "statusFilter=%i\n", status);
        list = ftd_list_next(list);
    }

    fclose(file);
    return;
}

/**
 * Geeft de configuratie-gegevens terug.
 * Geef het resultaat van deze functie niet vrij!
 *
 * @return  De configuratie-gegevens van FTD4linux.
 */
FtdConfig *
ftd_config_get(void)
{
    g_assert(core);

    return core->config;
}

/**
 * Maakt een nieuw configuratie-bestand aan.
 * In dit bestand staat niets dan een paar invoervelden met nepwaarden.
 */
void
ftd_config_create_dummy(void)
{
    FtdString *buf = ftd_string_new("");
    buf = ftd_string_append(buf, "# OpenFTD configuratie file\n");
    buf = ftd_string_append(buf, "# Alle regels die met '#' beginnen worden als commentaar beschouwd\n");
    buf = ftd_string_append(buf, "# Let op: alle commentaar regels worden automatisch verwijderd indien er\n");
    buf = ftd_string_append(buf, "# voor de eerste keer succesvol geupdated is\n");
    buf = ftd_string_append(buf, "username=<FTD username hier>\n");
    buf = ftd_string_append(buf, "password=<FTD password hier>\n");
    buf = ftd_string_append(buf, "# proxyHost=\n");
    buf = ftd_string_append(buf, "# proxyPort=\n");
    buf = ftd_string_append(buf, "# proxyUser=\n");
    buf = ftd_string_append(buf, "# proxyPassword=\n");
    buf = ftd_string_append(buf, "\n");

    ftd_file_save(CONFIG_FILE, buf, FALSE);

    ftd_string_free(buf);
}
