include(cmake_test/cmake_test)

ct_add_test(NAME "cpp_equal")
function("${cpp_equal}")
    include(cmakepp_lang/algorithm/equal)

    ct_add_section(NAME "signature")
    function("${signature}")
        set(CMAKEPP_LANG_DEBUG_MODE ON)

        ct_add_section(NAME "first_arg_desc" EXPECTFAIL)
        function("${first_arg_desc}")
            cpp_equal(TRUE lhs rhs)
        endfunction()

        ct_add_section(NAME "exactly_three" EXPECTFAIL)
        function("${exactly_three}")
            cpp_equal(result lhs rhs hello)
        endfunction()
    endfunction()

    ct_add_section(NAME "different_types")
    function("${different_types}")
        cpp_equal(result TRUE 1)
        ct_assert_equal(result FALSE)
    endfunction()

    ct_add_section(NAME "bool")
    function("${bool}")
        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_equal(result TRUE TRUE)
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            cpp_equal(result TRUE FALSE)
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()

    ct_add_section(NAME "descriptions")
    function("${descriptions}")
        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_equal(result "Hello World" "Hello World")
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            cpp_equal(result "Hello World" "foo bar")
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()

    ct_add_section(NAME "floats")
    function("${floats}")
        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_equal(result "3.14" "3.14")
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            cpp_equal(result "3.14" "1.23")
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()

    ct_add_section(NAME "ints")
    function("${ints}")
        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_equal(result 42 42)
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            cpp_equal(result 42 84)
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()

    ct_add_section(NAME "lists")
    function("${lists}")
        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_equal(result "Hello;World" "Hello;World")
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            cpp_equal(result "Hello;World" "Hello;bar")
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()

    ct_add_section(NAME "map")
    function("${map}")
        cpp_map(CTOR LHS foo bar hello world)

        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_map(CTOR RHS foo bar hello world)
            cpp_equal(result "${LHS}" "${RHS}")
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            cpp_map(CTOR RHS foo bar)
            cpp_equal(result "${LHS}" "${RHS}")
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()

    ct_add_section(NAME "objects")
    function("${objects}")
        include(cmakepp_lang/class/class)

        cpp_class(MyClass)
            cpp_attr(MyClass foo bar)
        cpp_end_class()

        MyClass(ctor LHS)
        MyClass(ctor RHS)

        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_equal(result "${LHS}" "${RHS}")
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            MyClass(SET "${RHS}" foo 42)
            cpp_equal(result "${LHS}" "${RHS}")
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()

    ct_add_section(NAME "equal_targets_lhs_equal_rhs")
    function(${equal_targets_lhs_equal_rhs})
        file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/a.c" "")
        add_library(a_lib "${CMAKE_CURRENT_BINARY_DIR}/a.c")
        cpp_equal(result a_lib a_lib)
        ct_assert_equal(result TRUE)
    endfunction()

    ct_add_section(NAME "equal_targets_lhs_not_equal_rhs")
    function(${equal_targets_lhs_not_equal_rhs})
        file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/a.c" "")
        add_library(lhs "${CMAKE_CURRENT_BINARY_DIR}/a.c")
        add_library(rhs "${CMAKE_CURRENT_BINARY_DIR}/a.c")
        cpp_equal(result lhs rhs)
        ct_assert_equal(result FALSE)
    endfunction()

    ct_add_section(NAME "types")
    function("${types}")
        ct_add_section(NAME "lhs_is_rhs")
        function("${lhs_is_rhs}")
            cpp_equal(result int int)
            ct_assert_equal(result TRUE)
        endfunction()

        ct_add_section(NAME "lhs_is_not_rhs")
        function("${lhs_is_not_rhs}")
            cpp_equal(result int bool)
            ct_assert_equal(result FALSE)
        endfunction()
    endfunction()
endfunction()
