# CMakeLists.txt for cforge v3.1.0
# Generated by cforge - C++ project management tool

cmake_minimum_required(VERSION 3.15)

# Project configuration
project(cforge VERSION 3.1.0 LANGUAGES CXX )

# Include compiler's implicit include directories in compile_commands.json
# This helps clangd and other tools find standard library headers
if(CMAKE_EXPORT_COMPILE_COMMANDS)
  set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif()

# Set source directory
set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

# Project description
set(PROJECT_DESCRIPTION "A C/C++ build tool with dependency management")
set(PROJECT_AUTHOR "Chase Sunstrom <casunstrom@gmail.com>")

string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER)
# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# platform detection
if(WIN32)
    set(CFORGE_PLATFORM "windows")
elseif(APPLE)
    set(CFORGE_PLATFORM "macos")
else()
    set(CFORGE_PLATFORM "linux")
endif()

# compiler detection
if(MSVC AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    set(CFORGE_COMPILER "msvc")
elseif(MINGW)
    set(CFORGE_COMPILER "mingw")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    if(APPLE)
        set(CFORGE_COMPILER "apple_clang")
    else()
        set(CFORGE_COMPILER "clang")
    endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    set(CFORGE_COMPILER "gcc")
else()
    set(CFORGE_COMPILER "unknown")
endif()
message(STATUS "platform: ${CFORGE_PLATFORM}, compiler: ${CFORGE_COMPILER}")

# CMake options
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Build configurations
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")
endif()

message(STATUS "Building with ${CMAKE_BUILD_TYPE} configuration")

# Configure output directories
if(DEFINED CMAKE_CONFIGURATION_TYPES)
  foreach(cfg IN LISTS CMAKE_CONFIGURATION_TYPES)
    string(TOUPPER ${cfg} CFG_UPPER)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_UPPER} "${CMAKE_BINARY_DIR}/lib/${cfg}")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_UPPER} "${CMAKE_BINARY_DIR}/lib/${cfg}")
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_UPPER} "${CMAKE_BINARY_DIR}/bin/${cfg}")
  endforeach()
else()
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}")
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}")
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}")
endif()

# Index dependencies via FetchContent
include(FetchContent)

# fmt v11.1.4
FetchContent_Declare(
    fmt
    GIT_REPOSITORY https://github.com/fmtlib/fmt.git
    GIT_TAG 11.1.4
    GIT_SHALLOW TRUE
)

# tomlplusplus v3.4.0
FetchContent_Declare(
    tomlplusplus
    GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
    GIT_TAG v3.4.0
    GIT_SHALLOW TRUE
)

# Fetch packages without setup commands
FetchContent_MakeAvailable(fmt tomlplusplus)

# Add source files
file(GLOB_RECURSE SOURCES
    "${SOURCE_DIR}/src/*.cpp"
    "${SOURCE_DIR}/src/*.c"
)

# Add target
add_executable(${PROJECT_NAME} ${SOURCES})

# Version definitions (from cforge.toml)
target_compile_definitions(${PROJECT_NAME} PUBLIC
    ${PROJECT_NAME_UPPER}_VERSION="${PROJECT_VERSION}"
    ${PROJECT_NAME_UPPER}_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
    ${PROJECT_NAME_UPPER}_VERSION_MINOR=${PROJECT_VERSION_MINOR}
    ${PROJECT_NAME_UPPER}_VERSION_PATCH=${PROJECT_VERSION_PATCH}
    PROJECT_VERSION="${PROJECT_VERSION}"
    PROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
    PROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR}
    PROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}
)

# Include directories
target_include_directories(${PROJECT_NAME} PUBLIC
    "${SOURCE_DIR}/include"
)

# Link FetchContent dependencies
target_link_libraries(${PROJECT_NAME} PUBLIC
    fmt::fmt
    tomlplusplus::tomlplusplus
)

# platform-specific configuration
if(CFORGE_PLATFORM STREQUAL "windows")
    target_compile_definitions(${PROJECT_NAME} PUBLIC NOMINMAX)
endif()

# Portable compiler flags per configuration
# Debug configuration flags
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    # Portable compiler flags
    if(MSVC AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        target_compile_options(${PROJECT_NAME} PRIVATE /Od /W4 /Zi /EHsc /GR)
    elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        target_compile_options(${PROJECT_NAME} PRIVATE -Og -Wall -Wextra -g -fdiagnostics-color=always)
    elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        target_compile_options(${PROJECT_NAME} PRIVATE -Og -Wall -Wextra -g -fcolor-diagnostics)
    endif()
endif()

# Release configuration flags
if(CMAKE_BUILD_TYPE STREQUAL "Release")
    # Portable compiler flags
    if(MSVC AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        target_compile_options(${PROJECT_NAME} PRIVATE /W4 /GL /EHsc /GR)
        target_link_options(${PROJECT_NAME} PRIVATE /LTCG)
    elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -flto -fdiagnostics-color=always)
        target_link_options(${PROJECT_NAME} PRIVATE -flto)
    elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -flto -fcolor-diagnostics)
        target_link_options(${PROJECT_NAME} PRIVATE -flto)
    endif()
endif()

# Definitions for config 'Debug'
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  target_compile_definitions(${PROJECT_NAME} PUBLIC DEBUG=1)
  target_compile_definitions(${PROJECT_NAME} PUBLIC FMT_UNICODE=0)
endif()

# platform-specific defines for windows
target_compile_definitions(${PROJECT_NAME} PUBLIC NOMINMAX)

# Link libraries
target_link_libraries(${PROJECT_NAME} PUBLIC
)

# compiler options
if(MSVC)
    target_compile_options(${PROJECT_NAME} PRIVATE /W4)
else()
    target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic)
endif()

# Tests
if(BUILD_TESTING)
    enable_testing()
    add_subdirectory("${SOURCE_DIR}/tests" ${CMAKE_BINARY_DIR}/tests)
endif()

# Installation configuration
include(GNUInstallDirs)

install(TARGETS ${PROJECT_NAME}
    RUNTIME
        DESTINATION ${CMAKE_INSTALL_BINDIR}
        COMPONENT Runtime
    LIBRARY
        DESTINATION ${CMAKE_INSTALL_LIBDIR}
        COMPONENT Runtime
    ARCHIVE
        DESTINATION ${CMAKE_INSTALL_LIBDIR}
        COMPONENT Runtime
)

if(MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug")
    install(FILES "$<TARGET_PDB_FILE:${PROJECT_NAME}>"
            DESTINATION ${CMAKE_INSTALL_BINDIR}
            COMPONENT Debug
            OPTIONAL
    )
endif()

# CPack configuration
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
set(CPACK_PACKAGE_VENDOR "Chase Sunstrom")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A C/C++ build tool with dependency management")
set(CPACK_PACKAGE_VERSION "3.1.0")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")

set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_BUILD_TYPE}")
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_RPM_COMPONENT_INSTALL ON)

# Package components
set(CPACK_COMPONENTS_ALL Runtime)

set(CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "Runtime Files")
set(CPACK_COMPONENT_RUNTIME_DESCRIPTION "Runtime libraries and executables")

if(WIN32)
    set(CPACK_GENERATOR "ZIP;NSIS")
    set(CPACK_NSIS_MODIFY_PATH ON)
    set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
    set(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME}")
    set(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME}")
    set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
elseif(APPLE)
    set(CPACK_GENERATOR "ZIP;TGZ")
else()
    set(CPACK_GENERATOR "ZIP;TGZ;DEB")
    set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}")
    set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
endif()

# Packaging directory settings
set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/packages")
set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")

# Override install prefix for packaging
set(CPACK_INSTALL_PREFIX )
include(CPack)
