#ifndef SUFFLE_HEADER
#define SUFFLE_HEADER

#include <time.h>

#include "MapReduce.h"

// Constants definitions:
#define DSuffleBatchFilePrefix "_batch"
#define DSuffleOutputFileName DMapReduceAuxiliarFilesDiretory DSuffleFilePrefix
//#define DSuffleBatchFileName DMapReduceAuxiliarFilesDiretory "_batch"

#define DMAX_LINES 256*1024
#define DMAX_FILES 32
#define DMAX_REDUCERS 16
#define DMAX_BATCHS 128
#define DBUFFER_IN_SIZE 16*4096
#define DBUFFER_OUT_SIZE 16*4096


// Types definitions:

/*
 * MapFile
 * -------
 * Represents a map output file that is being read incrementally
 * during the shuffle phase.
 *
 * The structure maintains an internal read buffer so that the program
 * can efficiently read data using the read() system call and reconstruct
 * lines from the incoming byte stream.
 */
typedef struct 
{
    int fd;                    /* File descriptor of the map output file */
    char buf[DBUFFER_IN_SIZE]; /* Internal buffer used to store blocks of bytes read from the file */
    int pos;                   /* Current reading position inside the buffer */
    int end;                   /* Index of the last valid byte in the buffer */
    int active;                /* Flag indicating whether the file still has data to be processed
                                  (1 = active, 0 = end of file reached) */
    int mapfile;
    int tuples;
} MapFile;


/*
 * RunFile
 * -------
 * Represents a temporary sorted run produced during the external
 * sorting phase of the shuffle stage.
 *
 * Each run file contains lines that are already sorted. During the
 * final merge phase, one line from each run is kept in memory so the
 * algorithm can repeatedly select the smallest one.
 */
typedef struct 
{
    int fd;                 /* File descriptor of the temporary run file */
    char buf[DBUFFER_IN_SIZE];
    int pos, end;
    char line[DMAX_LINE];    /* Buffer holding the current line read from the run */
    int active;             /* Indicates whether the run still contains unread lines
                               (1 = more lines available, 0 = end of run reached) */
} BatchFile;


typedef struct {
    int idx;
} HeapNode;

// Functions Prototypes
int cmp_lines(const void *a, const void *b);
void write_line(int fd, const char *line);
void flush_batch_out(int fd);
int read_line_map(MapFile *mf, char *line);
void flush_batch(int r);
void add_line(const char *line);
unsigned int hash_word(const char *str);
void extract_word(const char *line, char *word);
int read_line_batch(BatchFile *bf);
void merge_batchs(int r);
int suffle_process_files(int num_maps, char *map_files[], int num_reducers);
void wordcount_suffle(int nmappers, int nreducers);


#endif //MAPREDUCE_HEADER
