#include "test/framework/catch.hpp"
#include "src/shellmatta_opt.c"
#include <string.h>


TEST_CASE( "shellmatta_opt findNextHunk easy" ) {

    shellmatta_retCode_t ret = SHELLMATTA_OK;
    shellmatta_instance_t inst;
    char *dummyData = (char*) "This is Sparta";
    char buffer[1024u];

    memcpy(buffer, dummyData, strlen(dummyData));

    inst.buffer = buffer;
    inst.bufferSize = sizeof(buffer);
    inst.inputCount = 14;
    inst.optionParser.nextOffset = 4u;

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 5u);
    CHECK( inst.optionParser.len == 2u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 8u);
    CHECK( inst.optionParser.len == 6u);

    ret = findNextHunk(&inst);
    REQUIRE( ret == SHELLMATTA_ERROR );
}

TEST_CASE( "shellmatta_opt findNextHunk quotation 1" ) {

    shellmatta_retCode_t ret = SHELLMATTA_OK;
    shellmatta_instance_t inst;
    char *dummyData = (char*) "This is Sparta \"argument with spaces\"";
    char buffer[1024u];

    memcpy(buffer, dummyData, strlen(dummyData));

    inst.buffer = buffer;
    inst.bufferSize = sizeof(buffer);
    inst.inputCount = strlen(dummyData);
    inst.optionParser.nextOffset = 4u;

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 5u);
    CHECK( inst.optionParser.len == 2u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 8u);
    CHECK( inst.optionParser.len == 6u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 15u);
    CHECK( inst.optionParser.len == 20u);
    CHECK( 0 == memcmp(&(inst.buffer[inst.optionParser.offset]), "argument with spaces", 20));

    ret = findNextHunk(&inst);
    REQUIRE( ret == SHELLMATTA_ERROR );
}

TEST_CASE( "shellmatta_opt findNextHunk quotation 2" ) {

    shellmatta_retCode_t ret = SHELLMATTA_OK;
    shellmatta_instance_t inst;
    char *dummyData = (char*) "This is Sparta 'argument with spaces'";
    char buffer[1024u];

    memcpy(buffer, dummyData, strlen(dummyData));

    inst.buffer = buffer;
    inst.bufferSize = sizeof(buffer);
    inst.inputCount = strlen(dummyData);
    inst.optionParser.nextOffset = 4u;

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 5u);
    CHECK( inst.optionParser.len == 2u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 8u);
    CHECK( inst.optionParser.len == 6u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 15u);
    CHECK( inst.optionParser.len == 20u);
    CHECK( 0 == memcmp(&(inst.buffer[inst.optionParser.offset]), "argument with spaces", 20));

    ret = findNextHunk(&inst);
    REQUIRE( ret == SHELLMATTA_ERROR );
}

TEST_CASE( "shellmatta_opt findNextHunk quotation escaped" ) {

    shellmatta_retCode_t ret = SHELLMATTA_OK;
    shellmatta_instance_t inst;
    char *dummyData = (char*) "This is Sparta \"argument with \\\"spaces\"";
    char buffer[1024u];

    memcpy(buffer, dummyData, strlen(dummyData));

    inst.buffer = buffer;
    inst.bufferSize = sizeof(buffer);
    inst.inputCount = strlen(dummyData);
    inst.optionParser.nextOffset = 4u;

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 5u);
    CHECK( inst.optionParser.len == 2u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 8u);
    CHECK( inst.optionParser.len == 6u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 15u);
    CHECK( inst.optionParser.len == 21u);
    CHECK( 0 == memcmp(&(inst.buffer[inst.optionParser.offset]), "argument with \"spaces", 21));

    ret = findNextHunk(&inst);
    REQUIRE( ret == SHELLMATTA_ERROR );
}

TEST_CASE( "shellmatta_opt findNextHunk quotation missing closing quotation" ) {

    shellmatta_retCode_t ret = SHELLMATTA_OK;
    shellmatta_instance_t inst;
    char *dummyData = (char*) "This is Sparta \"argument with \\\"spaces";
    char buffer[1024u];

    memcpy(buffer, dummyData, strlen(dummyData));

    inst.buffer = buffer;
    inst.bufferSize = sizeof(buffer);
    inst.inputCount = strlen(dummyData);
    inst.optionParser.nextOffset = 4u;

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 5u);
    CHECK( inst.optionParser.len == 2u);

    ret = findNextHunk(&inst);
    CHECK( ret == SHELLMATTA_OK );
    CHECK( inst.optionParser.offset == 8u);
    CHECK( inst.optionParser.len == 6u);

    ret = findNextHunk(&inst);
    REQUIRE( ret == SHELLMATTA_ERROR );
}