/* See COPYING.txt for the full license governing this code. */
/**
 * \file sut_configparser.c
 *
 * Source file for the parser for SUT config files.
 */

#include <limits.h>
#include <string.h>
#include <SDL_test.h>
#include <SDL_rwops.h>
#include "SDL_visualtest_sut_configparser.h"
#include "SDL_visualtest_parsehelper.h"
#include "SDL_visualtest_rwhelper.h"

int
SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config)
{
    char line[MAX_SUTOPTION_LINE_LENGTH];
    SDLVisualTest_RWHelperBuffer buffer;
    char* token_ptr;
    char* token_end;
    int num_lines, i, token_len;
    SDL_RWops* rw;

    if(!file)
    {
        SDLTest_LogError("file argument cannot be NULL");
        return 0;
    }
    if(!config)
    {
        SDLTest_LogError("config argument cannot be NULL");
        return 0;
    }

    /* count the number of lines */
    rw = SDL_RWFromFile(file, "r");
    if(!rw)
    {
        SDLTest_LogError("SDL_RWFromFile() failed");
        return 0;
    }
    SDLVisualTest_RWHelperResetBuffer(&buffer);
    num_lines = SDLVisualTest_RWHelperCountNonEmptyLines(rw, &buffer, '#');
    if(num_lines == -1)
        return 0;
    else if(num_lines == 0)
    {
        config->options = NULL;
        config->num_options = 0;
        SDL_RWclose(rw);
        return 1;
    }

    /* allocate memory */
    SDL_RWseek(rw, 0, RW_SEEK_SET);
    SDLVisualTest_RWHelperResetBuffer(&buffer);
    config->num_options = num_lines;
    config->options = (SDLVisualTest_SUTOption*)SDL_malloc(num_lines * 
                      sizeof(SDLVisualTest_SUTOption));
    if(!config->options)
    {
        SDLTest_LogError("malloc() failed");
        SDL_RWclose(rw);
        return 0;
    }

    /* actually parse the options */
    for(i = 0; i < num_lines; i++)
    {
        if(!SDLVisualTest_RWHelperReadLine(rw, line, MAX_SUTOPTION_LINE_LENGTH,
                                           &buffer, '#'))
        {
            SDLTest_LogError("SDLVisualTest_RWHelperReadLine() failed");
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }

        /* parse name */
        token_ptr = strtok(line, ", ");
        if(!token_ptr)
        {
            SDLTest_LogError("Could not parse line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }
        token_len = SDL_strlen(token_ptr) + 1;
        SDL_strlcpy(config->options[i].name, token_ptr, token_len);

        /* parse type */
        token_ptr = strtok(NULL, ", ");
        if(!token_ptr)
        {
            SDLTest_LogError("Could not parse line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }
        if(SDL_strcmp(token_ptr, "string") == 0)
            config->options[i].type = SDL_SUT_OPTIONTYPE_STRING;
        else if(SDL_strcmp(token_ptr, "integer") == 0)
            config->options[i].type = SDL_SUT_OPTIONTYPE_INT;
        else if(SDL_strcmp(token_ptr, "enum") == 0)
            config->options[i].type = SDL_SUT_OPTIONTYPE_ENUM;
        else if(SDL_strcmp(token_ptr, "boolean") == 0)
            config->options[i].type = SDL_SUT_OPTIONTYPE_BOOL;
        else
        {
            SDLTest_LogError("Could not parse type token at line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }

        /* parse values */
        token_ptr = strtok(NULL, "]");
        if(!token_ptr)
        {
            SDLTest_LogError("Could not parse line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }
        token_ptr = SDL_strchr(token_ptr, '[');
        if(!token_ptr)
        {
            SDLTest_LogError("Could not parse enum token at line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }
        token_ptr++;
        if(config->options[i].type == SDL_SUT_OPTIONTYPE_INT)
        {
            if(SDL_sscanf(token_ptr, "%d %d", &config->options[i].data.range.min,
                          &config->options[i].data.range.max) != 2)
            {
                config->options[i].data.range.min = INT_MIN;
                config->options[i].data.range.max = INT_MAX;
            }
        }
        else if(config->options[i].type == SDL_SUT_OPTIONTYPE_ENUM)
        {
            config->options[i].data.enum_values = SDLVisualTest_Tokenize(token_ptr,
                                                  MAX_SUTOPTION_ENUMVAL_LEN);
            if(!config->options[i].data.enum_values)
            {
                SDLTest_LogError("Could not parse enum token at line %d", i + 1);
                SDL_free(config->options);
                SDL_RWclose(rw);
                return 0;
            }
        }

        /* parse required */
        token_ptr = strtok(NULL, ", ");
        if(!token_ptr)
        {
            SDLTest_LogError("Could not parse line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }

        if(SDL_strcmp(token_ptr, "true") == 0)
            config->options[i].required = SDL_TRUE;
        else if(SDL_strcmp(token_ptr, "false") == 0)
            config->options[i].required = SDL_FALSE;
        else
        {
            SDLTest_LogError("Could not parse required token at line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }

        /* parse categories */
        token_ptr = strtok(NULL, ",");
        if(!token_ptr)
        {
            SDLTest_LogError("Could not parse line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }
        token_ptr = SDL_strchr(token_ptr, '[');
        if(!token_ptr)
        {
            SDLTest_LogError("Could not parse enum token at line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }
        token_ptr++;
        token_end = SDL_strchr(token_ptr, ']');
        *token_end = '\0';
        if(!token_end)
        {
            SDLTest_LogError("Could not parse enum token at line %d", i + 1);
            SDL_free(config->options);
            SDL_RWclose(rw);
            return 0;
        }
        config->options[i].categories = SDLVisualTest_Tokenize(token_ptr,
                                        MAX_SUTOPTION_CATEGORY_LEN);
    }
    SDL_RWclose(rw);
    return 1;
}

void
SDLVisualTest_FreeSUTConfig(SDLVisualTest_SUTConfig* config)
{
    if(config && config->options)
    {
        SDLVisualTest_SUTOption* option;
        for(option = config->options;
            option != config->options + config->num_options; option++)
        {
            if(option->categories)
                SDL_free(option->categories);
            if(option->type == SDL_SUT_OPTIONTYPE_ENUM && option->data.enum_values)
                SDL_free(option->data.enum_values);
        }
        SDL_free(config->options);
        config->options = NULL;
        config->num_options = 0;
    }
}
