# ============================================================================
# Dynamics — 多语言引擎 CMake 构建系统
# ============================================================================
# 用法:
#   cmake -B build               # 配置（使用默认编译器）
#   cmake --build build           # 编译
#   cmake --build build --target dynamics_c    # 只编译 C 引擎
#
# 交叉编译:
#   cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-linux.cmake
#   cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw.cmake
#   cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-macos.cmake
# ============================================================================

cmake_minimum_required(VERSION 3.15)
project(DynamicsEngines
    VERSION 1.0.0
    DESCRIPTION "Multi-language molecular dynamics simulation engines"
    LANGUAGES C CXX Fortran
)

# ── 全局编译选项 ──────────────────────────────
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 优化等级（可被 -DCMAKE_BUILD_TYPE=Debug 覆盖）
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

# 统一编译选项
set(COMMON_C_FLAGS   -O3 -Wall -Wextra)
set(COMMON_CXX_FLAGS -O3 -Wall -Wextra)

# ── 统一输出目录：所有引擎可执行文件输出到 engines/<name>/build/ ────
#    这样 Python 的 run_engine() 可以在固定路径找到它们
function(add_engine_target name lang src)
    if(lang STREQUAL "C")
        add_executable(${name} ${src})
        target_compile_options(${name} PRIVATE ${COMMON_C_FLAGS})
        target_link_libraries(${name} PRIVATE m)
    elseif(lang STREQUAL "CXX")
        add_executable(${name} ${src})
        target_compile_options(${name} PRIVATE ${COMMON_CXX_FLAGS})
    elseif(lang STREQUAL "Fortran")
        enable_language(Fortran OPTIONAL)
        if(NOT CMAKE_Fortran_COMPILER)
            message(STATUS "Fortran compiler not found — skipping ${name}")
            return()
        endif()
        add_executable(${name} ${src})
    endif()

    # 从源码路径推导输出目录：engines/c/main.c → engines/c/build/
    # 这样 Python 的 run_engine() 能在固定路径找到可执行文件
    string(REGEX REPLACE "/[^/]+$" "/build" _out_subdir "${src}")
    set_target_properties(${name} PROPERTIES
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/${_out_subdir}"
    )
    # macOS 上禁止生成 .app 包（命令行工具不需要）
    set_target_properties(${name} PROPERTIES
        MACOSX_BUNDLE FALSE
    )
endfunction()

# ============================================================================
# 引擎目标定义
# ============================================================================

# ── C 引擎 ────────────────────────────────────
add_engine_target(dynamics_c  C  "engines/c/main.c")

# ── C++ 引擎 ──────────────────────────────────
add_engine_target(dynamics_cpp CXX "engines/cpp/main.cpp")

# ── Fortran 引擎 ──────────────────────────────
add_engine_target(dynamics_f90 Fortran "engines/fortran/main.f90")

# ============================================================================
# 自定义目标
# ============================================================================

# 编译所有引擎
add_custom_target(all-engines
    DEPENDS dynamics_c dynamics_cpp dynamics_f90
)

# 显示引擎信息
add_custom_target(info
    COMMAND ${CMAKE_COMMAND} -E echo "=== Dynamics Engines ==="
    COMMAND ${CMAKE_COMMAND} -E echo "C engine:       dynamics_c"
    COMMAND ${CMAKE_COMMAND} -E echo "C++ engine:     dynamics_cpp"
    COMMAND ${CMAKE_COMMAND} -E echo "Fortran engine: dynamics_f90"
    COMMAND ${CMAKE_COMMAND} -E echo ""
    COMMAND ${CMAKE_COMMAND} -E echo "Build: cmake --build ."
    COMMAND ${CMAKE_COMMAND} -E echo "Single: cmake --build . --target dynamics_c"
)

message(STATUS "DynamicsEngines ${PROJECT_VERSION}")
message(STATUS "  Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "  C compiler: ${CMAKE_C_COMPILER}")
message(STATUS "  C++ compiler: ${CMAKE_CXX_COMPILER}")
if(CMAKE_Fortran_COMPILER)
    message(STATUS "  Fortran compiler: ${CMAKE_Fortran_COMPILER}")
else()
    message(STATUS "  Fortran compiler: (not found, skipped)")
endif()
message(STATUS "")
message(STATUS "  Targets:")
message(STATUS "    cmake --build . --target dynamics_c")
message(STATUS "    cmake --build . --target dynamics_cpp")
message(STATUS "    cmake --build . --target dynamics_f90")
message(STATUS "    cmake --build . --target all-engines")
