/* See LICENSE.txt for the full license governing this code. */
/**
 * \file parsehelper.c
 *
 * Source file with some helper functions for parsing strings.
 */

#include <SDL_test.h>
#include "SDL_visualtest_harness_argparser.h"

/* this function uses a DFA to count the number of tokens in an agruments string.
   state 0 is taken to be the start and end state. State 1 handles a double quoted
   argument and state 2 handles unquoted arguments. */
static int
CountTokens(char* args)
{
    int index, num_tokens;
    int state; /* current state of the DFA */

    if(!args)
        return -1;

    index = 0;
    state = 0;
    num_tokens = 0;
    while(args[index])
    {
        char ch = args[index];
        switch(state)
        {
            case 0:
            if(ch == '\"')
            {
                state = 1;
                num_tokens++;
            }
            else if(!SDL_isspace(ch))
            {
                state = 2;
                num_tokens++;
            }
            break;

            case 1:
            if(ch == '\"')
            {
                state = 0;
            }
            break;

            case 2:
            if(SDL_isspace(ch))
            {
                state = 0;
            }
            break;
        }
        index++;
    }
    return num_tokens;
}

/* - size of tokens is num_tokens + 1
- uses the same DFA used in CountTokens() to split args into an array of strings */
static int
TokenizeHelper(char* str, char** tokens, int num_tokens, int max_token_len)
{
    int index, state, done, st_index, token_index;

    if(!str)
    {
        SDLTest_LogError("str argument cannot be NULL");
        return 0;
    }
    if(!tokens)
    {
        SDLTest_LogError("tokens argument cannot be NULL");
        return 0;
    }
    if(num_tokens <= 0)
    {
        SDLTest_LogError("num_tokens argument must be positive");
        return 0;
    }
    if(max_token_len <= 0)
    {
        SDLTest_LogError("max_token_len argument must be positive");
        return 0;
    }

    /* allocate memory for the tokens */
    tokens[num_tokens] = NULL;
    for(index = 0; index < num_tokens; index++)
    {
        tokens[index] = (char*)SDL_malloc(max_token_len);
        if(!tokens[index])
        {
            int i;
            SDLTest_LogError("SDL_malloc() failed.");
            for(i = 0; i < index; i++)
                SDL_free(tokens[i]);
            return 0;
        }
        tokens[index][0] = '\0';
    }

    /* copy the tokens into the array */
    st_index = 0;
    index = 0;
    token_index = 0;
    state = 0;
    done = 0;
    while(!done)
    {
        char ch = str[index];
        switch(state)
        {
            case 0:
            if(ch == '\"')
            {
                state = 1;
                st_index = index + 1;
            }
            else if(!ch)
                done = 1;
            else if(ch && !SDL_isspace(ch))
            {
                state = 2;
                st_index = index;
            }
            break;

            case 1:
            if(ch == '\"')
            {
                int i;
                state = 0;
                for(i = st_index; i < index; i++)
                {
                    tokens[token_index][i - st_index] = str[i];
                }
                tokens[token_index][i - st_index] = '\0';
                token_index++;
            }
            else if(!ch)
            {
                SDLTest_LogError("Parsing Error!");
                done = 1;
            }
            break;

            case 2:
            if(!ch)
                done = 1;
            if(SDL_isspace(ch) || !ch)
            {
                int i;
                state = 0;
                for(i = st_index; i < index; i++)
                {
                    tokens[token_index][i - st_index] = str[i];
                }
                tokens[token_index][i - st_index] = '\0';
                token_index++;
            }
            break;
        }
        index++;
    }
    return 1;
}

char**
SDLVisualTest_Tokenize(char* str, int max_token_len)
{
    int num_tokens;
    char** tokens;

    if(!str)
    {
        SDLTest_LogError("str argument cannot be NULL");
        return NULL;
    }
    if(max_token_len <= 0)
    {
        SDLTest_LogError("max_token_len argument must be positive");
        return NULL;
    }

    num_tokens = CountTokens(str);
    if(num_tokens == 0)
        return NULL;

    tokens = (char**)SDL_malloc(sizeof(char*) * (num_tokens + 1));
    if(!TokenizeHelper(str, tokens, num_tokens, max_token_len))
    {
        SDLTest_LogError("TokenizeHelper() failed");
        SDL_free(tokens);
        return NULL;
    }
    return tokens;
}

char**
SDLVisualTest_ParseArgsToArgv(char* args)
{
    char** argv;
    int num_tokens;

    num_tokens = CountTokens(args);
    if(num_tokens == 0)
        return NULL;

    /* allocate space for arguments */
    argv = (char**)SDL_malloc((num_tokens + 2) * sizeof(char*));
    if(!argv)
    {
        SDLTest_LogError("SDL_malloc() failed.");
        return NULL;
    }

    /* tokenize */
    if(!TokenizeHelper(args, argv + 1, num_tokens, MAX_SUT_ARGS_LEN))
    {
        SDLTest_LogError("TokenizeHelper() failed");
        SDL_free(argv);
        return NULL;
    }
    argv[0] = NULL;
    return argv;
}
