#include "../../test.h"
#include "arc/std/errno.h"
#include "arc/std/parser.h"
#include "arc/std/string.h"
#include "arc/std/parser/parserlang.h"

uint32_t TEST_PARSERLANG_ALPHA_CHAR = 24;

/* ~ parserlang tests ~ */
uint32_t TEST_ParserLang_GetIdFn(ARC_String *string){
    if(ARC_String_EqualsCStringWithStrlen(string, "<alphaChar>")){
        return TEST_PARSERLANG_ALPHA_CHAR;
    }

    if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_LOWER_CHAR")){
        return ARC_PARSERLANG_TOKEN_ALPHA_LOWER_CHAR;
    }

    if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_UPPER_CHAR")){
        return ARC_PARSERLANG_TOKEN_ALPHA_UPPER_CHAR;
    }

    return ~(uint32_t)0;
}

ARC_TEST(Parser_ParserLang_BasicTest){
    ARC_Parser *parser;
    ARC_ParserLang_CreateAsParser(&parser, TEST_ParserLang_GetIdFn);

    ARC_String *tempString;
    ARC_String_CreateWithStrlen(&tempString, "\n\n<alphaChar>    ->   ALPHA_LOWER_CHAR  |  ALPHA_UPPER_CHAR\n\n\n");

    //this destroys string, so no need for cleanup
    ARC_Parser_Parse(parser, &tempString);
    ARC_CHECK(arc_errno == 0);

    void *data = ARC_Parser_GetData(parser);
    ARC_ParserTag *tag = ARC_Vector_Get((ARC_Vector *)data, 0);

    ARC_CHECK(tag->tagId == TEST_PARSERLANG_ALPHA_CHAR);

    ARC_CHECK(tag->tokensOrTagsSize   ==                                     2);
    ARC_CHECK(tag->tokensOrTags[0][0] ==                                     1);
    ARC_CHECK(tag->tokensOrTags[0][1] == ARC_PARSERLANG_TOKEN_ALPHA_LOWER_CHAR);
    ARC_CHECK(tag->tokensOrTags[1][0] ==                                     1);
    ARC_CHECK(tag->tokensOrTags[1][1] == ARC_PARSERLANG_TOKEN_ALPHA_UPPER_CHAR);

    ARC_Parser_Destroy(parser);
}
