// Programa en C para contar el número de apariciones de un carácter en un fichero.
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h>
#include <time.h>

#include "Map.h"
#include "Reduce.h"
#include "Suffle.h"
#include "Errors.h"

// Global variables.
char pgm_help[]="   Sintax: \tWordCountMR [-m 'enable_multiple_mappers''] [-r <nreducers=1>] [-o <output_file>] <input_files>\n   Example: \tWordCountMR -m -r 1 -o ./Result/wc.txt ./Input/README.txt ./Input/LEEME.txt ./Input/LLEGEIXME.txt \n";

// Functions Prototypes
void wordcount(int ninputfiles, char *input_files[], char *output_file, bool multiple_mappers, int nreducers);

  
int main(int argc, char *argv[]) 
{ 
    bool MultipleMappers = false;
    int par, NReducers = 1;
    char *OutputFileName=NULL, MsgError[512];

    if (argc<2)
    {
        sprintf(MsgError,"Error number of arguments (%d arguments passed, at least 1 required).\n%s\n", argc-1, pgm_help);
        printMessage(MsgError, COLOR_RED);
        exit(1);
    }

    for(par=1;par<argc && argv[par][0]=='-';par++)
    {
        if (argv[par][0]=='-')
        {
            switch(argv[par][1])
            {
                case 'm':
                    MultipleMappers = true;
                    break;

                case 'r':
                    NReducers = atoi(argv[++par]);
                    break;

                case 'o':
                    OutputFileName = argv[++par];
                    break;

                default:
                    sprintf(MsgError,"Error optional argument %d is incorrect (%s).\n%s", par, argv[par], pgm_help);
                    Error(MsgError);                   
            }
        }
    }
    if (OutputFileName==NULL)
        OutputFileName = DReduceOutputFileName;

    setlocale(LC_ALL, "");

    wordcount(argc-par, &argv[par], OutputFileName, MultipleMappers, NReducers);

    exit(0);
}




/** 
 *  Function to perform the wordcount using map-reduce paradigm.
 */

void wordcount(int ninputfiles, char *input_files[], char *output_file, bool multiple_mappers, int nreducers)
{
    int words;
    struct timespec start, finish;
    float time;

    if (DEBUG) {
        sprintf(MsgDebug,"[WordCountMR:wordcount] wordcount %d %s %s %d %d\n", ninputfiles, input_files[0], output_file, multiple_mappers, nreducers);
        printDebug(MsgDebug);
    } 

    if (ninputfiles==1)
        multiple_mappers = false;

    clock_gettime(CLOCK_MONOTONIC, &start);

    // Mapper stage.
    words = wordcount_mapper(ninputfiles, input_files, multiple_mappers);

    // Suffle stage.
    if (multiple_mappers)
        wordcount_suffle(ninputfiles, nreducers);
    else
        wordcount_suffle(1, nreducers);

    // Reducer stage.
    wordcount_reducer(output_file, nreducers);    

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

    if (VERBOSE) {
        sprintf(MsgDebug,"[WordCountApp]  WordCount completed procesing %d files and %d words in %.3f secs.\n", ninputfiles, words, time);
        printMessage(MsgDebug, COLOR_GREEN_D);
    } 

}