cmake_minimum_required(VERSION 3.28)
project(core LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)

set(PRIVATE_MODULES
    "src/ErrorSimulator.cppm"
)

set(SRC
    "src/BitArray.cpp"
    "src/Box.cpp"
    "src/Buffer.cpp"
    "src/Clock.cpp"
    "src/CustomNewDelete.cpp"
    "src/File.cpp"
    "src/Frustum.cpp"
    "src/Logger.cpp"
    "src/Matrix.cpp"
    "src/Plane.cpp"
    "src/Quaternion.cpp"
    "src/Random.cpp"
    "src/ReadLine.cpp"
    "src/Terminal.cpp"
    "src/Test.cpp"
    "src/Thread.cpp"
    "src/ToString.cpp"
    "src/Unicode.cpp"
    "src/Utility.cpp"
    "src/Vector.cpp"
    "src/View.cpp"
)

set(SRC_TESTS
    "test/Main.cpp"
    "test/modules/ArrayListTests.cpp"
    "test/modules/ArrayTests.cpp"
    "test/modules/BitArrayTests.cpp"
    "test/modules/BoxTests.cpp"
    "test/modules/BufferTests.cpp"
    "test/modules/ClockTests.cpp"
    "test/modules/ColorTests.cpp"
    "test/modules/ComponentsTests.cpp"
    "test/modules/FileTests.cpp"
    "test/modules/FrustumTests.cpp"
    "test/modules/HashMapTests.cpp"
    "test/modules/HashedStringTests.cpp"
    "test/modules/ListTests.cpp"
    "test/modules/MathTests.cpp"
    "test/modules/MatrixTests.cpp"
    "test/modules/PlaneTests.cpp"
    "test/modules/QuaternionTests.cpp"
    "test/modules/QueueTests.cpp"
    "test/modules/RandomTests.cpp"
    "test/modules/ReadLineTests.cpp"
    "test/modules/TerminalTests.cpp"
    "test/modules/TestTests.cpp"
    "test/modules/ThreadTests.cpp"
    "test/modules/UnicodeTests.cpp"
    "test/modules/UniquePointerTests.cpp"
    "test/modules/UtilityTests.cpp"
    "test/modules/VectorTests.cpp"
    "test/modules/ViewTests.cpp"
)

set(SRC_PERFORMANCE
    "performance/Main.cpp"
)

if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    set(COMPILE_OPTIONS "")
    set(LINK_OPTIONS "")
    set(LOG_LEVEL 2)
    set(DEFINITIONS CHECK_MEMORY)
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
    set(COMPILE_OPTIONS "")
    set(LINK_OPTIONS "")
    set(LOG_LEVEL 3)
    set(DEFINITIONS CHECK_MEMORY)
else()
    set(DEFINITIONS ERROR_SIMULATOR CHECK_MEMORY)
    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        set(COMPILE_OPTIONS --coverage)
        set(LINK_OPTIONS gcov)
    elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        set(COMPILE_OPTIONS -fprofile-instr-generate -fcoverage-mapping)
        set(LINK_OPTIONS ${COMPILE_OPTIONS})
    endif()
    set(LOG_LEVEL 4)
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    include("cmake/gcc_warnings.cmake")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    include("cmake/clang_warnings.cmake")
endif()
include("cmake/add_modules.cmake")

add_library(core STATIC ${SRC})
target_compile_options(core PUBLIC
    ${COMPILE_OPTIONS}
    ${WARNINGS}
    -fdiagnostics-color=always
)
add_modules(
    TARGET core
    NAME public_modules
    FILES ${core_modules}
)
target_sources(core PUBLIC
    FILE_SET private_modules
    TYPE CXX_MODULES
    FILES ${PRIVATE_MODULES}
)
target_compile_definitions(core
    PRIVATE LOG_LEVEL=${LOG_LEVEL}
    PRIVATE ${DEFINITIONS}
)
target_link_libraries(core
    PRIVATE m ${LINK_OPTIONS}
)
install(TARGETS core FILE_SET public_modules DESTINATION .)
install(FILES cmake/add_modules.cmake DESTINATION cmake)

add_executable(test ${SRC_TESTS})
target_sources(test PUBLIC
    FILE_SET CXX_MODULES
    FILES test/Tests.cppm
)
target_link_libraries(test PRIVATE core)
target_compile_definitions(test PRIVATE ${DEFINITIONS})
target_compile_definitions(test
    PRIVATE LOG_LEVEL=4
)

add_executable(performance ${SRC_PERFORMANCE})
target_link_libraries(performance PRIVATE core)
target_compile_definitions(performance PRIVATE ${DEFINITIONS})
target_compile_definitions(performance
    PRIVATE LOG_LEVEL=4
)
