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

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

TEST_CASE( "Create simple integer table", "[integration]" ) {
    Script* script = Script::Create("table = {100, 50, 20, 5, -100, 50+50}");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto variable = script->GetVariable(u"table");
    REQUIRE(variable != nullptr);
    delete script;
    delete variable;
}

TEST_CASE( "Create simple string table", "[integration]" ) {
    Script* script = Script::Create("table = {'bla', 'test', 'foo', 'bar'}");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto variable = script->GetVariable(u"table");
    REQUIRE(variable != nullptr);
    delete script;
    delete variable;
}

TEST_CASE( "Index string table", "[integration]" ) {
    Script* script = Script::Create(
            R"(
table = {'bla', 'test', 'foo', 'bar'}
return table[3]
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    auto variable = script->Evaluate();
    REQUIRE(variable.Get() != nullptr);
    REQUIRE(variable->EvaluateString() == u"foo");
    delete script;
}

TEST_CASE( "Create complex table", "[integration]" ) {
    Script* script = Script::Create(
            R"(
table = {
    foo = 'test'
    bar = 100
}
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto variable = script->GetVariable(u"table");
    REQUIRE(variable != nullptr);
    auto table = (TableEvalValue*)variable;
    auto res = table->IndexValue("foo");
    auto res2 = table->IndexValue("bar");
    CHECK(res->EvaluateString() == u"test");
    CHECK(res2->EvaluateInteger() == 100);
    delete script;
    delete table;
    delete res;
    delete res2;
}

TEST_CASE( "Complex table with function", "[integration]" ) {
    Script* script = Script::Create(
            R"(
table = {
    local foo = 'test'
    function getFoo()
        return foo
    end
}
return table["getFoo"]()
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    auto variable = script->Evaluate();
    REQUIRE(variable.Get() != nullptr);
    delete script;
}


#endif

