# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(ProjectEuler CXX)

# Set C++ standard to C++23
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Use system default C++ compiler
# set(CMAKE_CXX_COMPILER clang++)

# Set compile flags
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -Wall -Wextra")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++23 -fPIC")

# Find required packages
find_package(PkgConfig REQUIRED)
find_package(Threads REQUIRED)

# Include directories
include_directories(${CMAKE_SOURCE_DIR}/include)

# Header-only library support
# Add header-only libraries by creating interface libraries
# Example: add_library(my_header_lib INTERFACE)
#          target_include_directories(my_header_lib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/external/my_header_lib/include)
#          target_link_libraries(${EXEC_NAME} my_header_lib)

# Add spdlog as a subdirectory
add_subdirectory(external/spdlog)

# Find all cpp files in src directory
file(GLOB_RECURSE ALL_SOURCE_FILES "src/*.cpp")

# Separate main files from other source files
set(NON_MAIN_SOURCE_FILES "")
set(MAIN_SOURCE_FILES "")

foreach(file ${ALL_SOURCE_FILES})
    # Check if file name contains 'main'
    if(file MATCHES ".*main.*\\.cpp$")
        list(APPEND MAIN_SOURCE_FILES ${file})
    else()
        list(APPEND NON_MAIN_SOURCE_FILES ${file})
    endif()
endforeach()

# Create a library from non-main source files
if(NON_MAIN_SOURCE_FILES)
    add_library(project_euler_lib ${NON_MAIN_SOURCE_FILES})
    target_link_libraries(project_euler_lib spdlog::spdlog)
    target_compile_features(project_euler_lib PRIVATE cxx_std_23)
endif()

# Create executables from main files
foreach(file ${MAIN_SOURCE_FILES})
    # Get the filename without extension
    get_filename_component(EXEC_NAME ${file} NAME_WE)
    
    # Create executable with project prefix
    set(FINAL_EXEC_NAME "ProjectEuler_${EXEC_NAME}")
    add_executable(${FINAL_EXEC_NAME} ${file})
    
    # Link the library to executable (if it exists)
    if(NON_MAIN_SOURCE_FILES)
        target_link_libraries(${FINAL_EXEC_NAME} project_euler_lib)
    endif()
    
    # Link spdlog library
    target_link_libraries(${FINAL_EXEC_NAME} spdlog::spdlog)
    
    # Set compile features
    target_compile_features(${FINAL_EXEC_NAME} PRIVATE cxx_std_23)
endforeach()