cmake_minimum_required(VERSION 3.15)
project(EquityCalculator)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Ottimizzazioni del compilatore per massime prestazioni
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
    
    # Flag di ottimizzazione aggressiva
    set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
    
    # Ottimizzazioni specifiche per architettura
    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math -funroll-loops")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto -fno-fat-lto-objects")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -finline-functions -finline-limit=300")
    endif()
    
    # Ottimizzazioni MSVC per Windows
    if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /Ob2 /Oi /Ot /GL")
        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG")
        set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LTCG")
    endif()
endif()

# Supporto OpenMP per parallelizzazione
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
    message(STATUS "OpenMP trovato - abilitando parallelizzazione")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
else()
    message(WARNING "OpenMP non trovato - compilazione senza parallelizzazione")
endif()

add_library(equity_calculator SHARED
src/card.cpp
src/deck.cpp
src/hand_evaluator.cpp
src/equity_calculator.cpp
src/equity_api.cpp
src/utils.cpp
)

# Crea anche una libreria statica per il linking con l'eseguibile
add_library(equity_calculator_static STATIC
src/card.cpp
src/deck.cpp
src/hand_evaluator.cpp
src/equity_calculator.cpp
src/equity_api.cpp
src/utils.cpp
)

target_include_directories(equity_calculator_static PUBLIC
${PROJECT_SOURCE_DIR}/include
)

if(OpenMP_CXX_FOUND)
    target_link_libraries(equity_calculator_static PUBLIC OpenMP::OpenMP_CXX)
endif()

# Definire equity_calculator_EXPORTS per la libreria statica per evitare dllimport
if (WIN32)
    target_compile_definitions(equity_calculator_static PRIVATE -Dequity_calculator_EXPORTS)
endif()

target_include_directories(equity_calculator PUBLIC
${PROJECT_SOURCE_DIR}/include
)

# Link OpenMP se disponibile
if(OpenMP_CXX_FOUND)
    target_link_libraries(equity_calculator PUBLIC OpenMP::OpenMP_CXX)
endif()

if (WIN32)
target_compile_definitions(equity_calculator PRIVATE -DEQUITYCALC_EXPORTS)
endif()

# Crea l'eseguibile principale
add_executable(TTMEval src/main.cpp)
target_link_libraries(TTMEval equity_calculator_static)
target_include_directories(TTMEval PRIVATE ${PROJECT_SOURCE_DIR}/include)

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

install(TARGETS equity_calculator TTMEval
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)

set(CMAKE_VERBOSE_MAKEFILE ON)
