# ---------------------------------------------------------------------
# Test fixture modules: one known-good stub, two deliberately broken
#
# The output paths come from the top-level file, which defines them
# before adding this directory so that each is written in one place.
# ---------------------------------------------------------------------
foreach(fixture good missing_symbols bad_version)
    add_library(fixture_${fixture} MODULE fixtures/src/${fixture}.cpp)
    set_target_properties(fixture_${fixture} PROPERTIES
            PREFIX ""
            SUFFIX ".so"
            OUTPUT_NAME ${fixture}
            LIBRARY_OUTPUT_DIRECTORY ${DPM_TEST_FIXTURE_DIR}
    )
endforeach()

# ---------------------------------------------------------------------
# API test binaries — one per area of the library, each its own ctest
# case, so a failure names the area it happened in
# ---------------------------------------------------------------------
foreach(suite context modules metadata aliases)
    add_executable(test_${suite} test_${suite}.cpp)

    target_link_libraries(test_${suite} PRIVATE dpm-core)

    target_include_directories(test_${suite} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

    target_compile_definitions(test_${suite} PRIVATE
            TEST_FIXTURE_MODULES="${DPM_TEST_FIXTURE_DIR}"
            TEST_FIXTURE_CONF="${CMAKE_CURRENT_SOURCE_DIR}/fixtures/conf"
            TEST_FIXTURE_METADATA="${CMAKE_CURRENT_SOURCE_DIR}/fixtures/metadata"
            TEST_SCRATCH_ROOT="${DPM_TEST_DIR}/scratch"
            DPM_CORE_VERSION_EXPECTED="${PROJECT_VERSION}"
    )

    set_target_properties(test_${suite} PROPERTIES
            RUNTIME_OUTPUT_DIRECTORY ${DPM_TEST_DIR}
            BUILD_RPATH "$ORIGIN/../lib"
    )

    foreach(fixture good missing_symbols bad_version)
        add_dependencies(test_${suite} fixture_${fixture})
    endforeach()

    add_test(NAME api_${suite} COMMAND test_${suite})
endforeach()

# ---------------------------------------------------------------------
# CLI end-to-end tests (the dpm binary is the cheapest full-stack client)
# ---------------------------------------------------------------------
set(CLI_FIXTURE_ARGS
        -c ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/conf
        -m ${CMAKE_BINARY_DIR}/modules
        -M ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/metadata
)

add_test(NAME cli_help COMMAND dpm --help)
set_tests_properties(cli_help PROPERTIES PASS_REGULAR_EXPRESSION "Usage: dpm")

add_test(NAME cli_help_lists_record_flags COMMAND dpm --help)
set_tests_properties(cli_help_lists_record_flags PROPERTIES
        PASS_REGULAR_EXPRESSION "--install-module")

add_test(NAME cli_list COMMAND dpm ${CLI_FIXTURE_ARGS} --list-modules)
set_tests_properties(cli_list PROPERTIES PASS_REGULAR_EXPRESSION "info")

# The bundled module has no record in the fixture directory, so the
# listing reports it as uninstalled rather than opening it.
add_test(NAME cli_list_marks_uninstalled
        COMMAND dpm ${CLI_FIXTURE_ARGS} --list-modules)
set_tests_properties(cli_list_marks_uninstalled PROPERTIES
        PASS_REGULAR_EXPRESSION "<uninstalled>")

add_test(NAME cli_info_version
        COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/conf
                    -m ${CMAKE_BINARY_DIR}/modules -L INFO info version)
set_tests_properties(cli_info_version PROPERTIES
        PASS_REGULAR_EXPRESSION "libdpm-core\\.so Version: ${PROJECT_VERSION}")

add_test(NAME cli_module_not_found
        COMMAND dpm ${CLI_FIXTURE_ARGS} nonexistent)
set_tests_properties(cli_module_not_found PROPERTIES WILL_FAIL TRUE)

add_test(NAME cli_rejects_invalid_module
        COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/conf
                    -m ${DPM_TEST_FIXTURE_DIR}
                    -M ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/metadata
                    missing_symbols)
set_tests_properties(cli_rejects_invalid_module PROPERTIES WILL_FAIL TRUE)

add_test(NAME cli_lists_aliases COMMAND dpm ${CLI_FIXTURE_ARGS} --list-aliases)
set_tests_properties(cli_lists_aliases PROPERTIES
        PASS_REGULAR_EXPRESSION "goodie")

add_test(NAME cli_lists_aliases_for_module
        COMMAND dpm ${CLI_FIXTURE_ARGS} --list-aliases good)
set_tests_properties(cli_lists_aliases_for_module PROPERTIES
        PASS_REGULAR_EXPRESSION "gd")

add_test(NAME cli_refuses_duplicate_alias
        COMMAND dpm ${CLI_FIXTURE_ARGS} --add-alias good goodie)
set_tests_properties(cli_refuses_duplicate_alias PROPERTIES WILL_FAIL TRUE)

add_test(NAME cli_add_alias_requires_two_arguments
        COMMAND dpm ${CLI_FIXTURE_ARGS} --add-alias good)
set_tests_properties(cli_add_alias_requires_two_arguments PROPERTIES
        WILL_FAIL TRUE)

add_test(NAME cli_uninstall_unrecorded_module
        COMMAND dpm ${CLI_FIXTURE_ARGS} --uninstall-module nonexistent)
set_tests_properties(cli_uninstall_unrecorded_module PROPERTIES WILL_FAIL TRUE)

# The install and uninstall round trip writes, so it runs against a
# scratch directory of its own and the two cases run in order.
add_test(NAME cli_install_module
        COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/conf
                    -m ${CMAKE_BINARY_DIR}/modules
                    -M ${DPM_TEST_DIR}/scratch/cli
                    --install-module info)

add_test(NAME cli_lists_installed_module
        COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/conf
                    -m ${CMAKE_BINARY_DIR}/modules
                    -M ${DPM_TEST_DIR}/scratch/cli
                    --list-modules)
set_tests_properties(cli_lists_installed_module PROPERTIES
        PASS_REGULAR_EXPRESSION "Reports and tests libdpm-core"
        DEPENDS cli_install_module)

add_test(NAME cli_uninstall_module
        COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/conf
                    -m ${CMAKE_BINARY_DIR}/modules
                    -M ${DPM_TEST_DIR}/scratch/cli
                    --uninstall-module info)
set_tests_properties(cli_uninstall_module PROPERTIES
        DEPENDS cli_lists_installed_module)
