#include <stdio.h>
#include <SDL.h>
#include <sys\types.h> 
#include <sys\stat.h>

#include "TextFileReader.h"
#include "Log.h"

void text_file_reader__read_lines(char* fileName, func_text_file_reader_on_line_read onLineReadCallback, void* extraParams)
{
    struct stat info;
    if (stat(fileName, &info) != 0) {
        log_write("Error: text file reader - file not found");
        return;
    }

    char* file = (Uint8*)malloc(info.st_size);
    if (file == NULL) {
        log_write("Error: text file reader - unable to allocate memory for file");
        return;
    }
    FILE* fp;
    errno_t result = fopen_s(&fp, fileName, "rb");
    if (result) {
        free(file);
        log_write("Error: text file reader - could not open file");
        return;
    }
    // try to read a single block of info.st_size bytes
    size_t blocks_read = fread(file, info.st_size, 1, fp);
    if (blocks_read != 1) {
        fclose(fp);
        free(file);
        log_write("Error: text file reader - could not read from file");
        return;
    }
    fclose(fp);

    char* line = (char*)malloc(1024 * sizeof(char));
    if (line == NULL) {
        free(file);
        log_write("Error: text file reader - could not allocate line buffer");
        return;
    }

    char* curCharInFile = file;
    char* curCharInLine = line;
    int position = 0;
    while (position < info.st_size) {
        if (*curCharInFile == '\r' || *curCharInFile == '\n') {
            // we've reached end of line
            *curCharInLine = 0; // terminate line string
            if (SDL_strlen(line) != 0) {
                onLineReadCallback(line, extraParams);
                // reset line
                curCharInLine = line;
            }
        }
        else {
            // regular character, so accumulate it
            *curCharInLine++ = *curCharInFile;
        }

        // next character
        curCharInFile++;
        position++;
    }
    // if we're in the middle of a line and the file contents ended, we have to
    // count this last line as well
    if (curCharInLine != line) {
        // line contains at least one character
        *curCharInLine = 0; // terminate line string
        onLineReadCallback(line, extraParams);
    }
    free(line);
    free(file);
}
