#include "../../test.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h"
#include "arc/std/parser/csv.h"
#include <stdlib.h>

void TEST_ParserCSV_CastTypeFn(void **data, ARC_String *string){
    int32_t *int32Data = (int32_t *)malloc(sizeof(int32_t));
    *int32Data = (int32_t)ARC_String_ToInt64_t(string);

    *data = (void *)int32Data;
}

void TEST_ParserCSV_DestroyTypeFn(void *data){
    free((int32_t *)data);
}

ARC_TEST(Parser_ParserCSV_BasicTest){
    ARC_Parser *parser;
    ARC_ParserCSV_CreateAsParser(&parser, ARC_False, TEST_ParserCSV_CastTypeFn, TEST_ParserCSV_DestroyTypeFn);

    const char *tempCString =
        "1,1,2,2\n"
        "2,3,4,5\n"
        "4,2,4,1\n"
        "7,7,7,7\n";

    ARC_String *tempString;
    ARC_String_CreateWithStrlen(&tempString, (char *)tempCString);

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

    ARC_ParserCSVData *data = (ARC_ParserCSVData *)ARC_Parser_GetData(parser);

    for(uint32_t y = 0; y < data->height; y++){
        for(uint32_t x = 0; x < data->width; x++){
            printf("%d ", *(int32_t *)(data->data[y][x]));
        }
        printf("\n");
    }

    ARC_Parser_Destroy(parser);
}

ARC_TEST(Parser_ParserCSV_BasicHeaderTest){
    ARC_Parser *parser;
    ARC_ParserCSV_CreateAsParser(&parser, ARC_True, TEST_ParserCSV_CastTypeFn, TEST_ParserCSV_DestroyTypeFn);

    const char *tempCString =
        "a,b,c,d\n"
        "4,3,2,1\n"
        "7,3,2,1\n"
        "4,2,4,1\n"
        "7,7,7,7\n";

    ARC_String *tempString;
    ARC_String_CreateWithStrlen(&tempString, (char *)tempCString);

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

    ARC_ParserCSVData *data = (ARC_ParserCSVData *)ARC_Parser_GetData(parser);

    for(uint32_t x = 0; x < data->width; x++){
        printf("%s ", data->headers[x]->data);
    }
    printf("\n");

    for(uint32_t y = 0; y < data->height; y++){
        for(uint32_t x = 0; x < data->width; x++){
            printf("%d ", *(int32_t *)(data->data[y][x]));
        }
        printf("\n");
    }

    ARC_Parser_Destroy(parser);
}
