include(FetchContent)

find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
  pkg_check_modules(CMOCKA QUIET cmocka>=2.0)
endif()

if(CMOCKA_FOUND)
  add_library(pid0_cmocka INTERFACE)
  target_include_directories(pid0_cmocka SYSTEM INTERFACE ${CMOCKA_INCLUDE_DIRS})
  target_link_libraries(pid0_cmocka INTERFACE ${CMOCKA_LINK_LIBRARIES})
  target_link_options(pid0_cmocka INTERFACE ${CMOCKA_LDFLAGS_OTHER})
  set(PID0_CMOCKA_TARGET pid0_cmocka)
else()
  set(WITH_CMOCKERY_SUPPORT OFF CACHE BOOL "" FORCE)
  set(WITH_EXAMPLES OFF CACHE BOOL "" FORCE)
  set(WITH_MALLOC_OVERRIDE OFF CACHE BOOL "" FORCE)
  set(WITH_STATIC_LIB ON CACHE BOOL "" FORCE)
  set(WITH_TESTS OFF CACHE BOOL "" FORCE)

  FetchContent_Declare(
    cmocka
    GIT_REPOSITORY https://gitlab.com/cmocka/cmocka.git
    GIT_TAG cmocka-2.0.2
    GIT_SHALLOW TRUE
  )
  FetchContent_MakeAvailable(cmocka)

  if(TARGET cmocka::cmocka)
    set(PID0_CMOCKA_TARGET cmocka::cmocka)
  elseif(TARGET cmocka)
    set(PID0_CMOCKA_TARGET cmocka)
  elseif(TARGET cmocka-static)
    add_library(pid0_cmocka ALIAS cmocka-static)
    set(PID0_CMOCKA_TARGET pid0_cmocka)
  else()
    message(FATAL_ERROR "Unable to determine the cmocka target name")
  endif()
  set(PID0_CMOCKA_SYSTEM_INCLUDE_DIR "${cmocka_SOURCE_DIR}/include")
endif()

add_executable(pid0-test-helper pid0_test_helper.c)
target_link_libraries(pid0-test-helper PRIVATE pid0::pid0)
target_include_directories(pid0-test-helper PRIVATE ${CMAKE_SOURCE_DIR}/src)
pid0_configure_c_executable(pid0-test-helper)
target_link_libraries(pid0-test-helper PRIVATE util)
set_target_properties(
  pid0-test-helper
  PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests
)

add_executable(pid0-unit-tests pid0_unit_test.c)
target_link_libraries(pid0-unit-tests PRIVATE pid0::pid0 ${PID0_CMOCKA_TARGET})
target_include_directories(pid0-unit-tests PRIVATE ${CMAKE_SOURCE_DIR}/src)
if(PID0_CMOCKA_SYSTEM_INCLUDE_DIR)
  target_include_directories(pid0-unit-tests SYSTEM PRIVATE ${PID0_CMOCKA_SYSTEM_INCLUDE_DIR})
endif()
target_compile_definitions(pid0-unit-tests PRIVATE inline=)
pid0_configure_c_executable(pid0-unit-tests)
set_target_properties(
  pid0-unit-tests
  PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests
)
add_test(NAME pid0-unit-tests COMMAND $<TARGET_FILE:pid0-unit-tests>)
set_tests_properties(pid0-unit-tests PROPERTIES LABELS "unit;local" TIMEOUT 10)

add_executable(pid0-single-header-unit-tests pid0_single_header_unit_test.c)
target_link_libraries(pid0-single-header-unit-tests PRIVATE ${PID0_CMOCKA_TARGET})
target_include_directories(
  pid0-single-header-unit-tests
  PRIVATE
    ${CMAKE_BINARY_DIR}/generated/include
)
if(PID0_CMOCKA_SYSTEM_INCLUDE_DIR)
  target_include_directories(pid0-single-header-unit-tests SYSTEM PRIVATE ${PID0_CMOCKA_SYSTEM_INCLUDE_DIR})
endif()
target_compile_definitions(pid0-single-header-unit-tests PRIVATE inline=)
pid0_configure_c_executable(pid0-single-header-unit-tests)
add_dependencies(pid0-single-header-unit-tests package-single-header)
set_target_properties(
  pid0-single-header-unit-tests
  PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests
)
add_test(
  NAME pid0-single-header-unit-tests
  COMMAND $<TARGET_FILE:pid0-single-header-unit-tests>
)
set_tests_properties(pid0-single-header-unit-tests PROPERTIES LABELS "unit;local" TIMEOUT 10)

add_test(
  NAME pid0-single-header-artifact-test
  COMMAND
    ${CMAKE_COMMAND}
      -DPID0_SINGLE_HEADER_BUILD=${PID0_SINGLE_HEADER_BUILD}
      -DPID0_SINGLE_HEADER_BUILD_ALIAS=${PID0_SINGLE_HEADER_BUILD_ALIAS}
      -DPID0_SINGLE_HEADER_DIST_GZ=${PID0_SINGLE_HEADER_DIST_GZ}
      -DPID0_VERSION=${PROJECT_VERSION}
      -P ${CMAKE_SOURCE_DIR}/tests/pid0_single_header_artifact_test.cmake
)
set_tests_properties(pid0-single-header-artifact-test PROPERTIES LABELS "packaging;local" TIMEOUT 10)

add_executable(pid0-integration-tests pid0_integration_test.c)
target_link_libraries(pid0-integration-tests PRIVATE ${PID0_CMOCKA_TARGET})
if(PID0_CMOCKA_SYSTEM_INCLUDE_DIR)
  target_include_directories(pid0-integration-tests SYSTEM PRIVATE ${PID0_CMOCKA_SYSTEM_INCLUDE_DIR})
endif()
target_compile_definitions(pid0-integration-tests PRIVATE inline=)
pid0_configure_c_executable(pid0-integration-tests)
target_compile_definitions(
  pid0-integration-tests
  PRIVATE
    PID0_TEST_HELPER_PATH="$<TARGET_FILE:pid0-test-helper>"
)
set_target_properties(
  pid0-integration-tests
  PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests
)
add_test(NAME pid0-integration-tests COMMAND $<TARGET_FILE:pid0-integration-tests>)
set_tests_properties(pid0-integration-tests PROPERTIES LABELS "integration;offline;local" TIMEOUT 20)

add_test(NAME pid0-container-smoke-test COMMAND ${CMAKE_SOURCE_DIR}/scripts/container-smoke-test.sh)
set_tests_properties(
  pid0-container-smoke-test
  PROPERTIES
    LABELS "example-smoke;local"
    SKIP_RETURN_CODE 77
    TIMEOUT 120
)

if(TARGET pid0-single-header-example)
  add_test(
    NAME pid0-single-header-example
    COMMAND
      ${CMAKE_COMMAND} -E env
        PID0_EXAMPLE_SLEEP_SECONDS=0
        $<TARGET_FILE:pid0-single-header-example>
        Example
  )
  set_tests_properties(pid0-single-header-example PROPERTIES LABELS "example-smoke;local" TIMEOUT 10)
endif()
