#include "test.h"
#include "codec/codec_ttl.h"

#define W3C_POS_TEST_CT 30
#define W3C_NEG_TEST_CT 14
#define W3C_TEST_BASE "http://www.w3.org/2001/sw/DataAccess/df1/tests/"


static LSUP_Triple trp[8];


/// Encode a graph as TTL.
int
test_encode_ttl_graph()
{
    log_info ("Test encoding graph document.");
    LSUP_Graph *gr = LSUP_graph_new (
            LSUP_iriref_new (NULL, NULL), LSUP_STORE_HTABLE, NULL, NULL, 0);
    if (!gr) return LSUP_MEM_ERR;

    size_t ins;
    LSUP_graph_add (gr, trp, &ins);

    char *out = calloc (1, 1);
    void *it = codec.encode_graph_init (gr);
    ASSERT (it != NULL, "Error creating codec iterator!");

    char *tmp = NULL;
    LSUP_rc rc;
    while ((rc = codec.encode_graph_iter (it, &tmp)) != LSUP_END) {
        log_info ("Serialized fragment: %s\n", tmp);
        ASSERT (rc >= 0, "Encoding step failed!");
        out = realloc (out, strlen(out) + strlen (tmp) + 1);
        out = strcat (out, tmp);
    }
    log_info ("Serialized graph: %s\n", out);
    codec.encode_graph_done (it);
    free (tmp);
    LSUP_graph_free (gr);

    /*
    for (int i = 0; i < 7; i++)
        ASSERT (strstr (out, end_nt_doc[i]) != NULL, end_nt_doc[i]);
    */
    free (out);

    return 0;
}


/// Positive test suite from W3C.
int
test_w3c_pos()
{
    char test_fname[36], out_fname[36];
    LSUP_Graph *gr;
    size_t ct;
    char *err;
    char ch;

    for (int i = 0; i <= W3C_POS_TEST_CT; i++) {
#if 1
        // Tests 14รท16 with 10K triples is quite long. Skip them temporarily.
        // TODO use a switch based on env var.
        if (i > 12 && i <17) continue;
#endif
        size_t nt_ct = 0;
        sprintf (test_fname, "test/assets/ttl/test-%02d.ttl", i);
        sprintf (out_fname, "test/assets/ttl/test-%02d.out", i);
        FILE *test_stream = fopen (test_fname, "r");
        FILE *out_stream = fopen (out_fname, "r");
        log_info ("Testing %s", test_fname);

        while ((ch=fgetc (out_stream)) != EOF) {
            if (ch == '\n') nt_ct++;
        }

        EXPECT_PASS (codec.decode_graph (test_stream, &gr, &ct, &err));
        EXPECT_INT_EQ (LSUP_graph_size (gr), nt_ct); // Just count NT lines.
        LSUP_graph_free (gr);
        fclose (test_stream);
        fclose (out_stream);
        free (err);
    }

    return 0;
}


/// Negative test suite from W3C.
int
test_w3c_neg()
{
    char test_fname[36];
    LSUP_Graph *gr;
    size_t ct;
    char *err;

    for (int i = 0; i <= W3C_NEG_TEST_CT; i++) {
        sprintf (test_fname, "test/assets/ttl/bad-%02d.ttl", i);
        FILE *test_stream = fopen (test_fname, "r");
        log_info ("Testing %s", test_fname);

        LSUP_rc rc = codec.decode_graph (test_stream, &gr, &ct, &err);
        log_info ("rc: %d", rc);
        ASSERT (rc == LSUP_PARSE_ERR, "Bad test did not raise a parse error!");
        fclose (test_stream);
        free (err);
    }

    return 0;
}


int codec_ttl_tests()
{
    LSUP_Term **terms = init_terms();
    init_triples (terms);

    codec = ttl_codec;

    RUN (test_encode_ttl_graph);
    //RUN (test_decode_nt_graph);
    //RUN (test_decode_nt_bad_graph);
    //RUN (test_w3c_pos);
    //RUN (test_w3c_neg);

    free_terms(terms);

    return 0;
}