#ifdef TESTS_BUILD
#include <catch.hpp>
#include "../src/Script.hpp"
using namespace Porygon;

TEST_CASE( "Create script variable", "[integration]" ) {
    Script* script = Script::Create("foo = true");
    REQUIRE(!script->Diagnostics -> HasErrors());
    auto variable = script->GetVariable(u"foo");
    REQUIRE(variable == nullptr);
    script->Evaluate();
    variable = script->GetVariable(u"foo");
    REQUIRE(variable != nullptr);
    REQUIRE(variable->EvaluateBool());
    delete script;
    delete variable;
}

TEST_CASE( "Create local variable", "[integration]" ) {
    Script* script = Script::Create("local foo = true");
    REQUIRE(!script->Diagnostics -> HasErrors());
    REQUIRE_FALSE(script->HasVariable(u"foo"));
    script->Evaluate();
    delete script;
}

TEST_CASE( "Create script variable and use", "[integration]" ) {
    Script* script = Script::Create("foo = false\n"
                                    "bar = not foo");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto variable = script->GetVariable(u"bar");
    REQUIRE(variable != nullptr);
    CHECK(variable->EvaluateBool());
    delete script;
    delete variable;
}

TEST_CASE( "Create local variable and use", "[integration]" ) {
    Script* script = Script::Create("local foo = false\n"
                                    "bar = not foo");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto variable = script->GetVariable(u"bar");
    REQUIRE(variable != nullptr);
    CHECK(variable->EvaluateBool());
    delete script;
    delete variable;
}

TEST_CASE( "Local variables in upmost scope persist", "[integration]" ) {
    Script* script = Script::Create(R"(
result = 0
local foo = 0
function bar()
    foo = foo + 1
    result = foo
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    script -> CallFunction(u"bar", {});
    script -> CallFunction(u"bar", {});
    auto variable = script->GetVariable(u"result");
    REQUIRE(variable != nullptr);
    CHECK(variable->EvaluateInteger() == 2);
    delete script;
    delete variable;
}

TEST_CASE( "Able to use emoji", "[integration]" ) {
    Script* script = Script::Create(uR"(
💩 = "LJ"
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    REQUIRE(script -> HasVariable(uR"(💩)"));
    auto variable = script->GetVariable(uR"(💩)");
    REQUIRE(variable != nullptr);
    CHECK(variable->EvaluateString() == u"LJ");
    delete script;
    delete variable;
}

#endif
