#include "Document.hh"
#include "utils.h"

Document::Document(Uri uri, char *buf, std::vector<gem_line> lines) : uri(std::move(uri)), buf(buf), lines(std::move(lines))
{
}

std::optional<Document> Document::parse(Uri uri, const char *buf)
{
    char *mutBuf = strdup(buf);

    gem_parse_state st{
        .buf = mutBuf,
        .preformatted = false};

    gem_line ln;

    std::vector<gem_line> lines;

    while (*st.buf)
    {
        switch (GemParseLine(&st, &ln))
        {
        case PARSE_FAIL:
            GcWarn("parsing document failed");
            free(mutBuf);
            return {};
        case PARSE_NOLINE:
            break;
        case PARSE_LINE:
            lines.push_back(ln);
            break;
        }
    }

    Document doc = Document(std::move(uri), mutBuf, std::move(lines));
    return {std::move(doc)};
}

std::optional<Document> Document::parse(const char *uriText, const char *buf)
{
    Uri uri;
    const char *errorPos;

    if (uriParseSingleUriA(uri, uriText, &errorPos) != 0)
    {
        GcWarn("parsing document URI failed");
        return {};
    }

    uriMakeOwnerA(uri);

    return parse(std::move(uri), buf);
}
