# SPDX-License-Identifier: MIT

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(test_${basename}
    VERSION 1.0.0
    LANGUAGES C)


string(REGEX REPLACE
    "/test/bacnet/[a-zA-Z_/-]*$"
    "/src"
    SRC_DIR
    ${CMAKE_CURRENT_SOURCE_DIR})
string(REGEX REPLACE
    "/test/bacnet/[a-zA-Z_/-]*$"
    "/test"
    TST_DIR
    ${CMAKE_CURRENT_SOURCE_DIR})
set(ZTST_DIR "${TST_DIR}/ztest/src")

add_compile_definitions(
    BACNET_BIG_ENDIAN=0
    CONFIG_ZTEST=1
    )

include_directories(
    ${SRC_DIR}
    ${TST_DIR}/ztest/include
    )

set(TEST_DEVICE_SOURCES
    # File(s) under test
    ${SRC_DIR}/bacnet/basic/object/device.c
    # Support files and stubs (pathname alphabetical)
    ${SRC_DIR}/bacnet/abort.c
    ${SRC_DIR}/bacnet/access_rule.c
    ${SRC_DIR}/bacnet/arf.c
    ${SRC_DIR}/bacnet/assigned_access_rights.c
    ${SRC_DIR}/bacnet/authentication_factor.c
    ${SRC_DIR}/bacnet/authentication_factor_format.c
    ${SRC_DIR}/bacnet/bacaction.c
    ${SRC_DIR}/bacnet/bacaudit.c
    ${SRC_DIR}/bacnet/bacaddr.c
    ${SRC_DIR}/bacnet/bacapp.c
    ${SRC_DIR}/bacnet/bacdcode.c
    ${SRC_DIR}/bacnet/bacdest.c
    ${SRC_DIR}/bacnet/bacdevobjpropref.c
    ${SRC_DIR}/bacnet/bacerror.c
    ${SRC_DIR}/bacnet/bacint.c
    ${SRC_DIR}/bacnet/baclog.c
    ${SRC_DIR}/bacnet/bacreal.c
    ${SRC_DIR}/bacnet/bacstr.c
    ${SRC_DIR}/bacnet/bactext.c
    ${SRC_DIR}/bacnet/bactimevalue.c
    ${SRC_DIR}/bacnet/basic/binding/address.c
    ${SRC_DIR}/bacnet/basic/object/acc.c
    ${SRC_DIR}/bacnet/basic/object/access_credential.c
    ${SRC_DIR}/bacnet/basic/object/access_door.c
    ${SRC_DIR}/bacnet/basic/object/access_point.c
    ${SRC_DIR}/bacnet/basic/object/access_rights.c
    ${SRC_DIR}/bacnet/basic/object/access_user.c
    ${SRC_DIR}/bacnet/basic/object/access_zone.c
    ${SRC_DIR}/bacnet/basic/object/ai.c
    ${SRC_DIR}/bacnet/basic/object/ao.c
    ${SRC_DIR}/bacnet/basic/object/auditlog.c
    ${SRC_DIR}/bacnet/basic/object/av.c
    ${SRC_DIR}/bacnet/basic/object/bacfile.c
    ${SRC_DIR}/bacnet/basic/object/bi.c
    ${SRC_DIR}/bacnet/basic/object/bitstring_value.c
    ${SRC_DIR}/bacnet/basic/object/blo.c
    ${SRC_DIR}/bacnet/basic/object/bo.c
    ${SRC_DIR}/bacnet/basic/object/bv.c
    ${SRC_DIR}/bacnet/basic/object/calendar.c
    ${SRC_DIR}/bacnet/basic/object/channel.c
    ${SRC_DIR}/bacnet/basic/object/color_object.c
    ${SRC_DIR}/bacnet/basic/object/color_temperature.c
    ${SRC_DIR}/bacnet/basic/object/command.c
    ${SRC_DIR}/bacnet/basic/object/credential_data_input.c
    ${SRC_DIR}/bacnet/basic/object/csv.c
    ${SRC_DIR}/bacnet/basic/object/iv.c
    ${SRC_DIR}/bacnet/basic/object/lc.c
    ${SRC_DIR}/bacnet/basic/object/lo.c
    ${SRC_DIR}/bacnet/basic/object/loop.c
    ${SRC_DIR}/bacnet/basic/object/lsp.c
    ${SRC_DIR}/bacnet/basic/object/lsz.c
    ${SRC_DIR}/bacnet/basic/object/ms-input.c
    ${SRC_DIR}/bacnet/basic/object/mso.c
    ${SRC_DIR}/bacnet/basic/object/msv.c
    ${SRC_DIR}/bacnet/basic/object/netport.c
    ${SRC_DIR}/bacnet/basic/object/osv.c
    ${SRC_DIR}/bacnet/basic/object/piv.c
    ${SRC_DIR}/bacnet/basic/object/program.c
    ${SRC_DIR}/bacnet/basic/object/schedule.c
    ${SRC_DIR}/bacnet/basic/object/structured_view.c
    ${SRC_DIR}/bacnet/basic/object/time_value.c
    ${SRC_DIR}/bacnet/basic/object/timer.c
    ${SRC_DIR}/bacnet/basic/object/trendlog.c
    ${SRC_DIR}/bacnet/basic/sys/bigend.c
    ${SRC_DIR}/bacnet/basic/sys/days.c
    ${SRC_DIR}/bacnet/basic/sys/debug.c
    ${SRC_DIR}/bacnet/basic/sys/keylist.c
    ${SRC_DIR}/bacnet/basic/sys/lighting_command.c
    ${SRC_DIR}/bacnet/basic/sys/linear.c
    ${SRC_DIR}/bacnet/datalink/bvlc.c
    ${SRC_DIR}/bacnet/datalink/bvlc6.c
    ${SRC_DIR}/bacnet/cov.c
    ${SRC_DIR}/bacnet/create_object.c
    ${SRC_DIR}/bacnet/credential_authentication_factor.c
    ${SRC_DIR}/bacnet/datetime.c
    ${SRC_DIR}/bacnet/delete_object.c
    ${SRC_DIR}/bacnet/dcc.c
    ${SRC_DIR}/bacnet/indtext.c
    ${SRC_DIR}/bacnet/hostnport.c
    ${SRC_DIR}/bacnet/lighting.c
    ${SRC_DIR}/bacnet/memcopy.c
    ${SRC_DIR}/bacnet/npdu.c
    ${SRC_DIR}/bacnet/proplist.c
    ${SRC_DIR}/bacnet/property.c
    ${SRC_DIR}/bacnet/reject.c
    ${SRC_DIR}/bacnet/shed_level.c
    ${SRC_DIR}/bacnet/timer_value.c
    ${SRC_DIR}/bacnet/timestamp.c
    ${SRC_DIR}/bacnet/wp.c
    ${SRC_DIR}/bacnet/weeklyschedule.c
    ${SRC_DIR}/bacnet/dailyschedule.c
    ${SRC_DIR}/bacnet/calendar_entry.c
    ${SRC_DIR}/bacnet/special_event.c
    ${SRC_DIR}/bacnet/channel_value.c
    ${SRC_DIR}/bacnet/secure_connect.c
    # Test and test library files
    ./src/main.c
    ${TST_DIR}/bacnet/basic/object/test/apdu_mock.c
    ${TST_DIR}/bacnet/basic/object/test/bip_mock.c
    ${TST_DIR}/bacnet/basic/object/test/cov_mock.c
    ${TST_DIR}/bacnet/basic/object/test/property_test.c
    ${TST_DIR}/bacnet/basic/object/test/datetime_local.c
    ${TST_DIR}/bacnet/basic/object/test/tsm_mock.c
    ${ZTST_DIR}/ztest_mock.c
    ${ZTST_DIR}/ztest.c
    )

function(configure_device_test_target
    target_name routing_enabled backup_restore_enabled)
    if(routing_enabled)
        target_sources(${target_name} PRIVATE
            ${SRC_DIR}/bacnet/basic/object/gateway/gw_device.c
            )
        target_compile_definitions(${target_name} PRIVATE
            BAC_ROUTING
            )
    endif()
    if(backup_restore_enabled)
        target_compile_definitions(${target_name} PRIVATE
            BACNET_BACKUP_RESTORE
            )
    endif()
endfunction()

# Register a CTest build/run pair for one device test binary.
function(
  add_device_ctest
  target_name
  test_name)
  add_test(NAME build_${test_name} COMMAND ${CMAKE_COMMAND} --build "${CMAKE_BINARY_DIR}" --config $<CONFIG> --target
                                           ${target_name})
  add_test(NAME test_${test_name} COMMAND $<TARGET_FILE:${target_name}>)
  set_tests_properties(test_${test_name} PROPERTIES FIXTURES_REQUIRED fixture_${test_name})
  set_tests_properties(build_${test_name} PROPERTIES FIXTURES_SETUP fixture_${test_name})
endfunction()

add_executable(${PROJECT_NAME}
    ${TEST_DEVICE_SOURCES}
    )
configure_device_test_target(${PROJECT_NAME} OFF OFF)

# Backup/Restore-only test binary.
add_executable(${PROJECT_NAME}_backup_restore ${TEST_DEVICE_SOURCES})
configure_device_test_target(
  ${PROJECT_NAME}_backup_restore
  OFF
  ON)

# BAC_ROUTING-only test binary.
add_executable(${PROJECT_NAME}_bac_routing ${TEST_DEVICE_SOURCES})
configure_device_test_target(
  ${PROJECT_NAME}_bac_routing
  ON
  OFF)

# BAC_ROUTING with Backup/Restore test binary.
add_executable(${PROJECT_NAME}_bac_routing_backup_restore ${TEST_DEVICE_SOURCES})
configure_device_test_target(
  ${PROJECT_NAME}_bac_routing_backup_restore
  ON
  ON)

# CTest pair for the Backup/Restore-only binary.
add_device_ctest(${PROJECT_NAME}_backup_restore ${basename}_backup_restore)
# CTest pair for the BAC_ROUTING-only binary.
add_device_ctest(${PROJECT_NAME}_bac_routing ${basename}_bac_routing)
# CTest pair for the BAC_ROUTING with Backup/Restore binary.
add_device_ctest(${PROJECT_NAME}_bac_routing_backup_restore ${basename}_bac_routing_backup_restore)
