#include "../../extern/doctest.hpp"
#include "../../src/Parser/Lexer/Lexer.hpp"

using namespace MalachScript::Parser;

#define STRING_TEST(str, constraint)                                                                                   \
    TEST_CASE("Lex string " constraint str constraint) {                                                               \
        MalachScript::Diagnostics::Logger diag;                                                                        \
        auto lexer = Lexer(u8##str, u8##constraint str constraint, &diag);                                             \
        const auto* token = lexer.Lex();                                                                               \
        CHECK(diag.GetMessages().empty());                                                                             \
        REQUIRE(token->GetKind() == LexTokenKind::StringLiteral);                                                      \
        auto value = ((const StringLiteral*)token)->GetValue();                                                        \
        CHECK(value == std::u8string(reinterpret_cast<const char8_t*>(str)));                                          \
        CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile);                                                 \
    }

STRING_TEST("foo bar", "'");
STRING_TEST("foo bar", "\"");
STRING_TEST("foo bar", "\"\"\"");
STRING_TEST("\"foo bar\"", "\"\"\"");
STRING_TEST("\"\"foo bar\"\"", "\"\"\"");

TEST_CASE("Lex multiline string") {
    MalachScript::Diagnostics::Logger diag;
    auto lexer = Lexer(u8"multiline", u8R"("""foo
bar""")",
                       &diag);
    const auto* token = lexer.Lex();
    CHECK(diag.GetMessages().empty());
    REQUIRE(token->GetKind() == LexTokenKind::StringLiteral);
    auto value = (dynamic_cast<const StringLiteral*>(token))->GetValue();
    CHECK(value == std::u8string(reinterpret_cast<const char8_t*>(R"(foo
bar)")));
    CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile);
}