#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <time.h>

#include "Map.h"
#include "Errors.h"

static char pgm_help[] =
    "   Sintax: \tWordCountMap [-i <map_id>] <input_files>\n"
    "   Example: \tWordCountMap -i 0 ./Input/README.txt\n";

static void build_map_output_name(char *out, size_t size, int map_id)
{
    if (map_id >= 0) {
        snprintf(out, size, "%s%s_%d%s",
                 DAuxiliarDiretory,
                 DMapFilePrefix,
                 map_id,
                 DAuxiliarFilesExtension);
    } else {
        snprintf(out, size, "%s", DMapOutputFileName);
    }
}

int main(int argc, char *argv[])
{
    int par = 1;
    int map_id = -1;
    int ninputfiles;
    int fd_out;
    int totalwords = 0;
    char map_file[512];
    struct timespec start, finish;
    float time;

    if (argc < 2) {
        printMessage("Error number of arguments.\n", COLOR_RED);
        printMessage(pgm_help, COLOR_RED);
        exit(1);
    }

    if (strcmp(argv[par], "-i") == 0) {
        if (argc < 4) {
            printMessage("Error missing map id or input file.\n", COLOR_RED);
            printMessage(pgm_help, COLOR_RED);
            exit(1);
        }

        map_id = atoi(argv[par + 1]);
        par += 2;
    }

    ninputfiles = argc - par;

    if (ninputfiles < 1) {
        printMessage("Error no input files.\n", COLOR_RED);
        printMessage(pgm_help, COLOR_RED);
        exit(1);
    }

    setlocale(LC_ALL, "");
    clock_gettime(CLOCK_MONOTONIC, &start);

    if (VERBOSE) {
        sprintf(Msg, "[Map Stage]\tStart Mapper to process %d input files.\n", ninputfiles);
        print(Msg);
    }

    build_map_output_name(map_file, sizeof(map_file), map_id);

    fd_out = open(map_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);

    if (fd_out < 0) {
        Error("[WordCountMap] Error opening mapper output file");
    }

    for (int i = 0; i < ninputfiles; i++) {
        int fd_in = open(argv[par + i], O_RDONLY);
        int words;

        if (fd_in < 0) {
            close(fd_out);
            Error("[WordCountMap] Error opening mapper input file");
        }

        words = map_process_file(fd_in, fd_out);
        totalwords += words;
        close(fd_in);

        if (VERBOSE) {
            sprintf(Msg, "\t\tMapper processed %d words from input file %d.\n",
                    words, i + 1);
            printMessage(Msg, COLOR_GREEN_L);
        }
    }

    close(fd_out);

    if (VERBOSE) {
        clock_gettime(CLOCK_MONOTONIC, &finish);
        time = (finish.tv_sec - start.tv_sec) +
               ((finish.tv_nsec - start.tv_nsec) / 1000000000.0);

        sprintf(Msg,
                "[Map Stage]\tMapper Done. Processed %d words from %d input files in %.3f secs.\n",
                totalwords, ninputfiles, time);
        print(Msg);
    }

    return totalwords;
}
