add_test(
    NAME VersionCommand
    COMMAND "${CMAKE_BINARY_DIR}/$<CONFIG>/fesa.exe" --version
)

set_tests_properties(
    VersionCommand
    PROPERTIES
        PASS_REGULAR_EXPRESSION "[0-9]+\\.[0-9]+\\.[0-9]+"
)

set_property(
    TEST VersionCommand
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_executable(fesa_dependency_smoke_test
    unit/dependencies/dependency_smoke_test.cpp
)

target_compile_features(fesa_dependency_smoke_test PRIVATE cxx_std_20)
target_compile_options(fesa_dependency_smoke_test PRIVATE /W4 /permissive- /EHsc)

target_link_libraries(fesa_dependency_smoke_test
    PRIVATE
        MKL::MKL
        TBB::tbb
        HDF5::HDF5
        GTest::gtest_main
        GTest::gtest
        GTest::gmock
)

add_test(
    NAME DependencySmoke
    COMMAND "$<TARGET_FILE:fesa_dependency_smoke_test>"
)

set_property(
    TEST DependencySmoke
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_test(
    NAME ProductionConfigureWithoutGTest
    COMMAND
        "${CMAKE_COMMAND}"
        --fresh
        -S "${CMAKE_SOURCE_DIR}"
        -B "${CMAKE_BINARY_DIR}/testing/production-no-gtest"
        -G "${CMAKE_GENERATOR}"
        -A "${CMAKE_GENERATOR_PLATFORM}"
        -T "${CMAKE_VS_PLATFORM_TOOLSET}"
        -DBUILD_TESTING=OFF
        -DCMAKE_DISABLE_FIND_PACKAGE_GTest=TRUE
        "-DMKL_DIR=${MKL_DIR}"
        "-DTBB_DIR=${TBB_DIR}"
        "-DHDF5_DIR=${HDF5_DIR}"
)

add_executable(fesa_core_value_tests
    unit/core/diagnostic_test.cpp
    unit/core/entity_id_test.cpp
    unit/core/status_test.cpp
    unit/core/vec3_test.cpp
    unit/core/version_test.cpp
)

target_compile_features(fesa_core_value_tests PRIVATE cxx_std_20)
target_compile_options(fesa_core_value_tests PRIVATE /W4 /permissive- /EHsc)

target_link_libraries(fesa_core_value_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME CoreValueTypes
    COMMAND "$<TARGET_FILE:fesa_core_value_tests>"
)

add_executable(fesa_model_value_tests
    unit/model/domain_builder_test.cpp
    unit/model/entity_origin_test.cpp
    unit/model/model_types_test.cpp
)

target_compile_features(fesa_model_value_tests PRIVATE cxx_std_20)
target_compile_options(fesa_model_value_tests PRIVATE /W4 /permissive- /EHsc)

target_link_libraries(fesa_model_value_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME ModelTypes
    COMMAND "$<TARGET_FILE:fesa_model_value_tests>" --gtest_filter=ModelTypes.*
)

add_test(
    NAME EntityOrigin
    COMMAND "$<TARGET_FILE:fesa_model_value_tests>" --gtest_filter=EntityOrigin.*
)

add_test(
    NAME DomainBuilder
    COMMAND "$<TARGET_FILE:fesa_model_value_tests>" --gtest_filter=DomainBuilder.*
)

add_test(
    NAME DomainValidation
    COMMAND "$<TARGET_FILE:fesa_model_value_tests>" --gtest_filter=*DomainValidation*
)

add_executable(fesa_abaqus_parser_tests
    unit/io/abaqus/active_input_test.cpp
    unit/io/abaqus/input_contract_test.cpp
    unit/io/abaqus/material_section_mapping_test.cpp
    unit/io/abaqus/parser_test.cpp
    unit/io/abaqus/set_resolution_test.cpp
)

target_compile_features(fesa_abaqus_parser_tests PRIVATE cxx_std_20)
target_compile_options(fesa_abaqus_parser_tests PRIVATE /W4 /permissive- /EHsc)
target_compile_definitions(
    fesa_abaqus_parser_tests
    PRIVATE
        FESA_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
)

target_link_libraries(fesa_abaqus_parser_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME AbaqusParser
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=AbaqusParser.*
)

add_test(
    NAME ScopedDeck
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=ScopedDeck.*
)

add_test(
    NAME AbaqusInputContract
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=AbaqusInputContract/*
)

add_test(
    NAME SetResolution
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=SetResolution.*
)

add_test(
    NAME PartSet
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=PartSet.*
)

add_test(
    NAME AssemblySet
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=AssemblySet.*
)

add_test(
    NAME ActiveInput
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=ActiveInput.*
)

add_test(
    NAME SemanticScope
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=SemanticScope.*
)

add_test(
    NAME MaterialMapping
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=MaterialMapping.*
)

add_test(
    NAME BeamSection
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=BeamSection.*
)

add_test(
    NAME ShearDefault
    COMMAND "$<TARGET_FILE:fesa_abaqus_parser_tests>"
        --gtest_filter=ShearDefault.*
)

add_executable(fesa_deck_to_domain_tests
    integration/io/minimal_deck_to_domain_test.cpp
)

target_compile_features(fesa_deck_to_domain_tests PRIVATE cxx_std_20)
target_compile_options(fesa_deck_to_domain_tests PRIVATE /W4 /permissive- /EHsc)
target_compile_definitions(
    fesa_deck_to_domain_tests
    PRIVATE
        FESA_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
)

target_link_libraries(fesa_deck_to_domain_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME DeckToDomain
    COMMAND "$<TARGET_FILE:fesa_deck_to_domain_tests>"
        --gtest_filter=DeckToDomain.*
)

add_test(
    NAME SingleInstance
    COMMAND "$<TARGET_FILE:fesa_deck_to_domain_tests>"
        --gtest_filter=ActiveInstance.*
)

add_test(
    NAME StepMapping
    COMMAND "$<TARGET_FILE:fesa_deck_to_domain_tests>"
        --gtest_filter=StepMapping.*
)

add_test(
    NAME Boundary
    COMMAND "$<TARGET_FILE:fesa_deck_to_domain_tests>"
        --gtest_filter=Boundary.*
)

add_test(
    NAME Cload
    COMMAND "$<TARGET_FILE:fesa_deck_to_domain_tests>"
        --gtest_filter=Cload.*
)

add_test(
    NAME SuppliedCantilever
    COMMAND "$<TARGET_FILE:fesa_deck_to_domain_tests>"
        --gtest_filter=SuppliedCantilever.*
)

add_executable(fesa_fem_primitives_tests
    unit/fem/beam_frame_test.cpp
    unit/fem/dof_manager_test.cpp
    unit/fem/gauss_rule_test.cpp
    unit/fem/line2_shape_test.cpp
)

target_compile_features(fesa_fem_primitives_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_fem_primitives_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_fem_primitives_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME Quadrature
    COMMAND "$<TARGET_FILE:fesa_fem_primitives_tests>"
        --gtest_filter=Quadrature.*
)

add_test(
    NAME ShapeFunction
    COMMAND "$<TARGET_FILE:fesa_fem_primitives_tests>"
        --gtest_filter=ShapeFunction.*
)

add_test(
    NAME Jacobian
    COMMAND "$<TARGET_FILE:fesa_fem_primitives_tests>"
        --gtest_filter=Jacobian.*
)

add_test(
    NAME DofManager
    COMMAND "$<TARGET_FILE:fesa_fem_primitives_tests>"
        --gtest_filter=DofManager.*
)

add_test(
    NAME EquationNumbering
    COMMAND "$<TARGET_FILE:fesa_fem_primitives_tests>"
        --gtest_filter=EquationNumbering.*
)

add_test(
    NAME BeamFrame
    COMMAND "$<TARGET_FILE:fesa_fem_primitives_tests>"
        --gtest_filter=BeamFrame.*
)

add_test(
    NAME BeamTransformation
    COMMAND "$<TARGET_FILE:fesa_fem_primitives_tests>"
        --gtest_filter=BeamTransformation.*
)

add_executable(fesa_beam3d2_tests
    unit/elements/beam3d2_test.cpp
)

target_compile_features(fesa_beam3d2_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_beam3d2_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_beam3d2_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME Beam3D2
    COMMAND "$<TARGET_FILE:fesa_beam3d2_tests>"
        --gtest_filter=Beam3D2.*
)

add_test(
    NAME Timoshenko
    COMMAND "$<TARGET_FILE:fesa_beam3d2_tests>"
        --gtest_filter=Timoshenko.*
)

add_test(
    NAME RigidBody
    COMMAND "$<TARGET_FILE:fesa_beam3d2_tests>"
        --gtest_filter=RigidBody.*
)

add_test(
    NAME BeamRecovery
    COMMAND "$<TARGET_FILE:fesa_beam3d2_tests>"
        --gtest_filter=BeamRecovery.*
)

add_test(
    NAME SectionForce
    COMMAND "$<TARGET_FILE:fesa_beam3d2_tests>"
        --gtest_filter=SectionForce.*
)

add_test(
    NAME CentroidStress
    COMMAND "$<TARGET_FILE:fesa_beam3d2_tests>"
        --gtest_filter=CentroidStress.*
)

add_executable(fesa_serial_assembly_tests
    unit/assembly/serial_assembler_test.cpp
)

target_compile_features(fesa_serial_assembly_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_serial_assembly_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_serial_assembly_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME SparsePattern
    COMMAND "$<TARGET_FILE:fesa_serial_assembly_tests>"
        --gtest_filter=SparsePattern.*
)

add_test(
    NAME SerialAssembly
    COMMAND "$<TARGET_FILE:fesa_serial_assembly_tests>"
        --gtest_filter=SerialAssembly.*
)

add_test(
    NAME SymmetricCsr
    COMMAND "$<TARGET_FILE:fesa_serial_assembly_tests>"
        --gtest_filter=SymmetricCsr.*
)

add_test(
    NAME CanonicalContribution
    COMMAND "$<TARGET_FILE:fesa_serial_assembly_tests>"
        --gtest_filter=CanonicalContribution.*
)

add_test(
    NAME DeterministicMerge
    COMMAND "$<TARGET_FILE:fesa_serial_assembly_tests>"
        --gtest_filter=DeterministicMerge.*
)

add_executable(fesa_parallel_assembly_tests
    unit/assembly/parallel_assembler_test.cpp
)

target_compile_features(fesa_parallel_assembly_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_parallel_assembly_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_parallel_assembly_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME ParallelAssembly
    COMMAND "$<TARGET_FILE:fesa_parallel_assembly_tests>"
        --gtest_filter=ParallelAssembly.*
)

add_test(
    NAME TbbElementEvaluation
    COMMAND "$<TARGET_FILE:fesa_parallel_assembly_tests>"
        --gtest_filter=TbbElementEvaluation.*
)

set_property(
    TEST ParallelAssembly TbbElementEvaluation
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_executable(fesa_thread_count_determinism_tests
    integration/assembly/thread_count_determinism_test.cpp
)

target_compile_features(
    fesa_thread_count_determinism_tests PRIVATE cxx_std_20
)
target_compile_options(
    fesa_thread_count_determinism_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_thread_count_determinism_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME ThreadCountDeterminism
    COMMAND "$<TARGET_FILE:fesa_thread_count_determinism_tests>"
)

set_property(
    TEST ThreadCountDeterminism
    PROPERTY ENVIRONMENT "MKL_NUM_THREADS=1"
)
set_property(
    TEST ThreadCountDeterminism
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_executable(fesa_constraint_tests
    unit/constraints/essential_bc_test.cpp
)

target_compile_features(fesa_constraint_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_constraint_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_constraint_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME EssentialBc
    COMMAND "$<TARGET_FILE:fesa_constraint_tests>"
        --gtest_filter=EssentialBc.*
)

add_test(
    NAME ConstraintElimination
    COMMAND "$<TARGET_FILE:fesa_constraint_tests>"
        --gtest_filter=ConstraintElimination.*
)

add_test(
    NAME Reaction
    COMMAND "$<TARGET_FILE:fesa_constraint_tests>"
        --gtest_filter=Reaction.*
)

add_executable(fesa_linear_solver_tests
    unit/solvers/linear/pardiso_linear_solver_test.cpp
)

target_compile_features(fesa_linear_solver_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_linear_solver_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_linear_solver_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME PardisoLinearSolver
    COMMAND "$<TARGET_FILE:fesa_linear_solver_tests>"
)

set_property(
    TEST PardisoLinearSolver
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_executable(fesa_result_database_tests
    unit/results/result_database_test.cpp
)

target_compile_features(fesa_result_database_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_result_database_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_result_database_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME NodalFrame
    COMMAND "$<TARGET_FILE:fesa_result_database_tests>"
        --gtest_filter=NodalFrame.*
)

add_test(
    NAME ResultDatabase
    COMMAND "$<TARGET_FILE:fesa_result_database_tests>"
        --gtest_filter=ResultDatabase.*
)

add_test(
    NAME ElementFrame
    COMMAND "$<TARGET_FILE:fesa_result_database_tests>"
        --gtest_filter=ElementFrame.*
)

add_test(
    NAME ResultContractMetadata
    COMMAND "$<TARGET_FILE:fesa_result_database_tests>"
        --gtest_filter=CompleteResultContract.*
)

add_executable(fesa_hdf5_results_tests
    integration/io/hdf5_results_test.cpp
)

target_compile_features(fesa_hdf5_results_tests PRIVATE cxx_std_20)
target_compile_options(
    fesa_hdf5_results_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)
target_compile_definitions(
    fesa_hdf5_results_tests
    PRIVATE
        FESA_TEST_BINARY_DIR="${CMAKE_BINARY_DIR}"
)

target_link_libraries(fesa_hdf5_results_tests
    PRIVATE
        fesa_core
        HDF5::HDF5
        GTest::gtest_main
)

add_test(
    NAME Hdf5
    COMMAND "$<TARGET_FILE:fesa_hdf5_results_tests>"
        --gtest_filter=Hdf5.*
)

add_test(
    NAME ResultRoundTrip
    COMMAND "$<TARGET_FILE:fesa_hdf5_results_tests>"
        --gtest_filter=ResultRoundTrip.*
)

add_test(
    NAME SelfContainedHdf5
    COMMAND "$<TARGET_FILE:fesa_hdf5_results_tests>"
        --gtest_filter=SelfContainedHdf5.*
)

set_property(
    TEST Hdf5 ResultRoundTrip SelfContainedHdf5
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_executable(fesa_linear_static_analysis_tests
    unit/analysis/linear_static_analysis_test.cpp
)

target_compile_features(
    fesa_linear_static_analysis_tests PRIVATE cxx_std_20
)
target_compile_options(
    fesa_linear_static_analysis_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)

target_link_libraries(fesa_linear_static_analysis_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME LinearStaticAnalysis
    COMMAND "$<TARGET_FILE:fesa_linear_static_analysis_tests>"
        --gtest_filter=LinearStaticAnalysis.*
)

add_test(
    NAME StaticEquilibrium
    COMMAND "$<TARGET_FILE:fesa_linear_static_analysis_tests>"
        --gtest_filter=StaticEquilibrium.*
)

add_test(
    NAME CompleteResultContract
    COMMAND "$<TARGET_FILE:fesa_linear_static_analysis_tests>"
        --gtest_filter=CompleteResultContract.*
)

set_property(
    TEST LinearStaticAnalysis StaticEquilibrium CompleteResultContract
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_executable(fesa_pipeline_integration_tests
    integration/pipeline/minimal_cantilever_test.cpp
)

target_compile_features(
    fesa_pipeline_integration_tests PRIVATE cxx_std_20
)
target_compile_options(
    fesa_pipeline_integration_tests
    PRIVATE
        /W4
        /permissive-
        /EHsc
)
target_compile_definitions(
    fesa_pipeline_integration_tests
    PRIVATE
        FESA_CLI_PATH="$<TARGET_FILE:fesa>"
        FESA_TEST_BINARY_DIR="${CMAKE_BINARY_DIR}"
        FESA_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
)
target_link_libraries(fesa_pipeline_integration_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)
add_dependencies(fesa_pipeline_integration_tests fesa)

add_test(
    NAME MinimalCantileverPipeline
    COMMAND "$<TARGET_FILE:fesa_pipeline_integration_tests>"
        --gtest_filter=MinimalCantileverPipeline.*
)

set_property(
    TEST MinimalCantileverPipeline
    PROPERTY ENVIRONMENT_MODIFICATION
        ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
)

add_executable(fesa_validation_comparison_tests
    unit/validation/comparison_test.cpp
)

target_compile_features(
    fesa_validation_comparison_tests PRIVATE cxx_std_20
)
target_compile_options(
    fesa_validation_comparison_tests PRIVATE /W4 /permissive- /EHsc
)
target_link_libraries(
    fesa_validation_comparison_tests
    PRIVATE
        fesa_core
        GTest::gtest_main
)

add_test(
    NAME ComparisonMetric
    COMMAND "$<TARGET_FILE:fesa_validation_comparison_tests>"
        --gtest_filter=ComparisonMetric.*
)

add_test(
    NAME EntityMatching
    COMMAND "$<TARGET_FILE:fesa_validation_comparison_tests>"
        --gtest_filter=EntityMatching.*
)
