#include "xreatemanager.h"
#include "gtest/gtest.h"
using namespace xreate;
//DEBT implement no pkgconfig ways to link libs

//TOTEST FunctionUnit::compileInline
TEST(Compilation, DISABLED_functionInline1){
}

TEST(Compilation, functionEntry1){
    std::unique_ptr<XreateManager> program(XreateManager::prepare(
        "func1 = function(a:: int):: int {a+8} \
         func2 = function::int; entry {12 + func1(4)}      \
        "));

    void* entryPtr = program->run();
    int (*entry)() = (int (*)())(intptr_t)entryPtr;

    int answer = entry();
    ASSERT_EQ(24, answer);
}

TEST(Compilation, full_IFStatementWithVariantType){
    XreateManager* man = XreateManager::prepare(
        "Color = type variant (RED, BLUE, GREEN).\n"
        "\n"
        "   main = function(x::int):: bool; entry {\n"
        "       color = if (x == 0 )::Color {RED} else {BLUE}.\n"
        "       if (color == BLUE)::bool {true} else {false}\n"
        "   }"
    );

    bool (*main)(int) = (bool (*)(int)) man->run();
    ASSERT_FALSE(main(0));
    ASSERT_TRUE(main(1));
}

TEST(Compilation, full_StructUpdate){
    XreateManager* man = XreateManager::prepare(
    R"Code(

    Rec = type alias  {
        a :: int,
        b:: int
    }.

    test= function:: int; entry {
        a = {a = 18, b = 20}:: Rec.

        b = a + {a = 11}:: Rec.
        b["a"]
    }
    )Code");

    int (*main)() = (int (*)()) man->run();
    int result = main();

    ASSERT_EQ(11, result);
}

TEST(Compilation, AnonymousStruct_init_index){
    std::string code =
R"Code(

    main = function:: int; entry {
        x = {10, 15} :: {int, int}.
        x[1]
    }

)Code";

    std::unique_ptr<XreateManager> man(XreateManager::prepare(move(code)));
    int (*main)() = (int (*)()) man->run();

    EXPECT_EQ(15, main());
}

TEST(Compilation, AnonymousStruct_init_update){
    std::string code =
R"Code(

    main = function:: int; entry {
        x = {10, 15} :: {int, int}.
        y = x + {6}:: {int, int}.
        y[0]
    }

)Code";

    std::unique_ptr<XreateManager> man(XreateManager::prepare(move(code)));
    int (*main)() = (int (*)()) man->run();

    EXPECT_EQ(6, main());
}

