#include "common.h"
#include "display.h"
#include "compress.h"
#include "decompress.h"
#include "arguments.h"

#include <stdlib.h>
#include <argp.h>
#include <libintl.h>
#include <locale.h>
#include <string.h>

// Nom, version du programme et adresse pour les bugs
// (ces informations sont affichées dans l'aide)
const char *argp_program_version = "huffman 0.1";
const char *argp_program_bug_address =
   "<matteo.delabre@etu.umontpellier.fr>";

// Définition de la configuration de Argp, qui affichera
// ces informations dans la page d'aide entre autres
static struct argp_option options[] = {
    {
        .name = "decompress",
        .key = 'd',
        .doc = "Décompresse SOURCE vers DEST"
    },
    {
        .name = "verbose",
        .key = 'v',
        .doc = "Affiche des informations de débogage"
    },
    {0}
};

static struct argp argp = {
    .options = options,
    .parser = parseArgument,
    .args_doc = "SOURCE [DEST]",
    .doc = "Compresse SOURCE vers DEST (par défaut, vers la sortie standard) "
        "en utilisant l'algorithme de Huffman"
};

int main(int argc, char** argv) {
    // Paramètres de langue. Utilisation de la locale de l'utilisateur,
    // et des messages traduits dans libc (pour pallier à un bug de argp)
    setlocale(LC_ALL, "");
    textdomain("libc");

    // Valeurs par défaut des arguments optionnels
    Args args = {
        .verbose = FALSE,
        .compress = TRUE,
        .source = NULL,
        .dest = stdout
    };

    // Interprétation des arguments passés au programme, résultat
    // dans `args`. Arrêt en cas d'erreur
    if (argp_parse(&argp, argc, argv, 0, 0, &args)) {
        return EXIT_FAILURE;
    }

    // Passage en mode verbeux si demandé
    setVerbose(args.verbose);

    // Compression ou décompression du flux d'entrée vers le flux de sortie
    if (args.compress) {
        compress(args.source, args.dest);
    } else {
        decompress(args.source, args.dest);
    }

    // Fermeture des flux et sortie
    fclose(args.source);
    fclose(args.dest);

    return EXIT_SUCCESS;
}
