if(POLICY CMP0167)
    cmake_policy(SET CMP0167 OLD)
endif()

add_library(regimeflow_common
    common/config.cpp
    common/json.cpp
    common/time.cpp
    common/types.cpp
    common/yaml_config.cpp
    common/sha256.cpp
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    target_compile_options(regimeflow_common PRIVATE -Wno-free-nonheap-object)
endif()

set(IBAPI_ROOT "${CMAKE_SOURCE_DIR}/third_party/ibapi/IBJts/source/cppclient/client")
if(ENABLE_IBAPI AND EXISTS "${IBAPI_ROOT}")
    file(GLOB IBAPI_SOURCES "${IBAPI_ROOT}/*.cpp")
    set(IBAPI_PROTO_DIR "${IBAPI_ROOT}/protobufUnix")
    file(GLOB IBAPI_PROTO_SOURCES "${IBAPI_PROTO_DIR}/*.pb.cc")
    add_library(ibapi STATIC ${IBAPI_SOURCES} ${IBAPI_PROTO_SOURCES})
    target_include_directories(ibapi PUBLIC ${IBAPI_ROOT} ${IBAPI_PROTO_DIR})
    if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
        target_compile_options(ibapi PRIVATE -w)
    elseif(MSVC)
        target_compile_options(ibapi PRIVATE /w)
    endif()
    set(_regimeflow_required_protobuf_version 3.21.12)
    set(_regimeflow_protobuf_target "")
    find_package(Protobuf ${_regimeflow_required_protobuf_version} QUIET)
    set(_protobuf_has_required_headers OFF)
    if(Protobuf_FOUND)
        foreach(_proto_inc IN LISTS Protobuf_INCLUDE_DIRS)
            if(EXISTS "${_proto_inc}/google/protobuf/port_def.inc"
               AND EXISTS "${_proto_inc}/google/protobuf/map_field_inl.h")
                set(_protobuf_has_required_headers ON)
                break()
            endif()
        endforeach()
        if(_protobuf_has_required_headers)
            if(TARGET protobuf::libprotobuf)
                set(_regimeflow_protobuf_target protobuf::libprotobuf)
            elseif(TARGET protobuf::protobuf)
                set(_regimeflow_protobuf_target protobuf::protobuf)
            endif()
        endif()
    endif()
    if(NOT Protobuf_FOUND OR NOT _protobuf_has_required_headers)
        if(REGIMEFLOW_FETCH_DEPS)
            include(FetchContent)
            FetchContent_Declare(
                protobuf
                URL https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.21.12.zip
            )
            set(protobuf_BUILD_TESTS OFF CACHE BOOL "" FORCE)
            set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
            set(protobuf_INSTALL OFF CACHE BOOL "" FORCE)
            FetchContent_MakeAvailable(protobuf)
            set(Protobuf_FOUND TRUE)
            set(Protobuf_INCLUDE_DIRS "${protobuf_SOURCE_DIR}/src")
            set(Protobuf_VERSION "${_regimeflow_required_protobuf_version}")
            if(TARGET libprotobuf)
                set(_regimeflow_protobuf_target libprotobuf)
            elseif(TARGET protobuf::libprotobuf)
                set(_regimeflow_protobuf_target protobuf::libprotobuf)
            endif()
        else()
            message(FATAL_ERROR "Protobuf >= ${_regimeflow_required_protobuf_version} is required for the bundled IB API generated sources.")
        endif()
    endif()
    target_include_directories(ibapi PUBLIC ${Protobuf_INCLUDE_DIRS})
    find_package(Threads REQUIRED)
    target_link_libraries(ibapi PUBLIC Threads::Threads)
    if(_regimeflow_protobuf_target)
        target_link_libraries(ibapi PUBLIC ${_regimeflow_protobuf_target})
    else()
        target_link_libraries(ibapi PUBLIC ${Protobuf_LIBRARIES})
    endif()
    set(IBAPI_NEEDS_BID_COMPAT OFF)
    if(EXISTS "/usr/local/lib/libbid.a")
        target_link_libraries(ibapi PUBLIC /usr/local/lib/libbid.a)
    elseif(EXISTS "/opt/homebrew/lib/libbid.a")
        target_link_libraries(ibapi PUBLIC /opt/homebrew/lib/libbid.a)
    else()
        find_library(IBAPI_BID_LIBRARY NAMES
            bid
            bidgcc000
            bidgcc001
            bidgcc010
            bidgcc011
            bidgcc100
            bidgcc101
            bidgcc110
            bidgcc111
            bidvc
            bidvc141
            bidvc142
            bidvc143
            bidvc144
            HINTS /opt/homebrew/lib /usr/local/lib ${_vcpkg_lib_hints}
        )
        if(IBAPI_BID_LIBRARY)
            target_link_libraries(ibapi PUBLIC ${IBAPI_BID_LIBRARY})
        endif()
    endif()
    if((APPLE OR WIN32) AND NOT IBAPI_BID_LIBRARY)
        set(IBAPI_NEEDS_BID_COMPAT ON)
    endif()
    if(IBAPI_NEEDS_BID_COMPAT)
        target_sources(ibapi PRIVATE ${CMAKE_SOURCE_DIR}/src/live/ib_bid_compat.cpp)
        target_compile_definitions(ibapi PUBLIC REGIMEFLOW_IBAPI_SOFTBID)
    endif()
endif()

set(REGIMEFLOW_PUBLIC_INCLUDE
    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

function(regimeflow_target_public_include target)
    target_include_directories(${target} PUBLIC ${REGIMEFLOW_PUBLIC_INCLUDE})
endfunction()

function(regimeflow_enable_windows_exports target)
    if(WIN32 AND BUILD_SHARED_LIBS)
        set_target_properties(${target} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
    endif()
endfunction()

regimeflow_target_public_include(regimeflow_common)
regimeflow_enable_windows_exports(regimeflow_common)

add_library(regimeflow_data
    data/alpaca_data_client.cpp
    data/alpaca_data_source.cpp
    data/api_data_source.cpp
    data/bar_builder.cpp
    data/corporate_actions.cpp
    data/csv_reader.cpp
    data/data_validation.cpp
    data/data_source_factory.cpp
    data/db_csv_adapter.cpp
    data/db_client.cpp
    data/db_source.cpp
    data/live_feed.cpp
    data/memory_data_source.cpp
    data/merged_iterator.cpp
    data/metadata_data_source.cpp
    data/mmap_data_source.cpp
    data/mmap_reader.cpp
    data/mmap_storage.cpp
    data/mmap_writer.cpp
    data/order_book_mmap.cpp
    data/order_book_mmap_data_source.cpp
    data/postgres_client.cpp
    data/snapshot_access.cpp
    data/symbol_metadata.cpp
    data/tick_mmap.cpp
    data/tick_mmap_data_source.cpp
    data/time_series_query.cpp
    data/tick_csv_reader.cpp
    data/validation_utils.cpp
    data/websocket_feed.cpp
)

regimeflow_target_public_include(regimeflow_data)
regimeflow_enable_windows_exports(regimeflow_data)

target_link_libraries(regimeflow_data
    PUBLIC
        regimeflow_common
        regimeflow_plugins
)

if(ENABLE_POSTGRES)
find_package(PostgreSQL QUIET)
if(PostgreSQL_FOUND)
    target_compile_definitions(regimeflow_data PRIVATE REGIMEFLOW_USE_LIBPQ)
    if(TARGET PostgreSQL::PostgreSQL)
        target_link_libraries(regimeflow_data PRIVATE PostgreSQL::PostgreSQL)
    else()
        target_include_directories(regimeflow_data PRIVATE ${PostgreSQL_INCLUDE_DIRS})
        target_link_libraries(regimeflow_data PRIVATE ${PostgreSQL_LIBRARIES})
    endif()
    set(REGIMEFLOW_PACKAGE_NEEDS_POSTGRES ON PARENT_SCOPE)
endif()
endif()

if(ENABLE_CURL)
find_package(CURL QUIET)
if(CURL_FOUND)
    target_compile_definitions(regimeflow_data PRIVATE REGIMEFLOW_USE_CURL)
    if(TARGET CURL::libcurl)
        target_link_libraries(regimeflow_data PRIVATE CURL::libcurl)
    else()
        target_include_directories(regimeflow_data PRIVATE ${CURL_INCLUDE_DIRS})
        target_link_libraries(regimeflow_data PRIVATE ${CURL_LIBRARIES})
    endif()
    set(REGIMEFLOW_PACKAGE_NEEDS_CURL ON PARENT_SCOPE)
endif()
endif()

find_package(Boost QUIET COMPONENTS system)
set(REGIMEFLOW_BOOST_WEBSOCKET_HEADERS_FOUND OFF)
if(Boost_FOUND)
    foreach(_boost_include IN LISTS Boost_INCLUDE_DIRS)
        if(EXISTS "${_boost_include}/boost/asio/io_context.hpp"
           AND EXISTS "${_boost_include}/boost/beast/core.hpp")
            set(REGIMEFLOW_BOOST_WEBSOCKET_HEADERS_FOUND ON)
            break()
        endif()
    endforeach()
endif()
if(Boost_FOUND AND REGIMEFLOW_BOOST_WEBSOCKET_HEADERS_FOUND)
    target_compile_definitions(regimeflow_data PUBLIC REGIMEFLOW_USE_BOOST_BEAST)
    if(TARGET Boost::headers)
        target_link_libraries(regimeflow_data PUBLIC Boost::headers Boost::system)
    elseif(TARGET Boost::boost)
        target_link_libraries(regimeflow_data PUBLIC Boost::boost Boost::system)
    else()
        target_include_directories(regimeflow_data
            PUBLIC
                $<BUILD_INTERFACE:${Boost_INCLUDE_DIRS}>
        )
        target_link_libraries(regimeflow_data PUBLIC Boost::system)
    endif()
    set(REGIMEFLOW_PACKAGE_NEEDS_BOOST_SYSTEM ON PARENT_SCOPE)
endif()

if(ENABLE_OPENSSL)
find_package(OpenSSL QUIET)
if(OpenSSL_FOUND)
    target_compile_definitions(regimeflow_data PUBLIC REGIMEFLOW_USE_OPENSSL)
    target_link_libraries(regimeflow_data PRIVATE OpenSSL::SSL OpenSSL::Crypto)
    set(REGIMEFLOW_PACKAGE_NEEDS_OPENSSL ON PARENT_SCOPE)
endif()
endif()

add_executable(regimeflow_mmap_builder tools/mmap_builder.cpp)
target_link_libraries(regimeflow_mmap_builder PRIVATE regimeflow_data)

add_executable(regimeflow_alpaca_fetch tools/alpaca_fetch_main.cpp)
target_link_libraries(regimeflow_alpaca_fetch PRIVATE regimeflow_data)

add_library(regimeflow_engine
    engine/audit_log.cpp
    engine/backtest_engine.cpp
    engine/backtest_results.cpp
    engine/backtest_runner.cpp
    engine/dashboard_snapshot.cpp
    engine/engine_factory.cpp
    engine/execution_pipeline.cpp
    engine/event_generator.cpp
    engine/event_loop.cpp
    engine/market_data_cache.cpp
    engine/order_book_cache.cpp
    engine/order.cpp
    engine/order_manager.cpp
    engine/order_routing.cpp
    engine/portfolio.cpp
    engine/regime_tracker.cpp
    engine/parity_checker.cpp
    engine/timer_service.cpp
)

regimeflow_target_public_include(regimeflow_engine)
regimeflow_enable_windows_exports(regimeflow_engine)

target_link_libraries(regimeflow_engine
    PUBLIC
        regimeflow_common
        regimeflow_data
        regimeflow_execution
        regimeflow_risk
        regimeflow_metrics
        regimeflow_regime
        regimeflow_plugins
)

add_library(regimeflow_execution
    execution/basic_execution_model.cpp
    execution/commission.cpp
    execution/execution_factory.cpp
    execution/fill_simulator.cpp
    execution/latency_model.cpp
    execution/market_impact.cpp
    execution/order_book_execution_model.cpp
    execution/slippage.cpp
    execution/transaction_cost.cpp
)

regimeflow_target_public_include(regimeflow_execution)
regimeflow_enable_windows_exports(regimeflow_execution)

target_link_libraries(regimeflow_execution
    PUBLIC
        regimeflow_common
        regimeflow_plugins
)

add_library(regimeflow_strategy
    strategy/context.cpp
    strategy/strategy_factory.cpp
    strategy/strategy_manager.cpp
    strategy/strategies/buy_and_hold.cpp
    strategy/strategies/harmonic_pattern.cpp
    strategy/strategies/moving_average_cross.cpp
    strategy/strategies/pairs_trading.cpp
    strategy/strategies/register_builtin.cpp
)

regimeflow_target_public_include(regimeflow_strategy)
regimeflow_enable_windows_exports(regimeflow_strategy)

target_link_libraries(regimeflow_strategy
    PUBLIC
        regimeflow_common
        regimeflow_engine
        regimeflow_plugins
)

add_library(regimeflow_risk
    risk/risk_factory.cpp
    risk/risk_limits.cpp
    risk/position_sizer.cpp
    risk/stop_loss.cpp
)

regimeflow_target_public_include(regimeflow_risk)
regimeflow_enable_windows_exports(regimeflow_risk)

target_link_libraries(regimeflow_risk
    PUBLIC
        regimeflow_common
        regimeflow_plugins
)

add_library(regimeflow_metrics
    metrics/attribution.cpp
    metrics/drawdown.cpp
    metrics/live_performance.cpp
    metrics/metrics_tracker.cpp
    metrics/performance.cpp
    metrics/performance_calculator.cpp
    metrics/performance_metrics.cpp
    metrics/regime_attribution.cpp
    metrics/transition_metrics.cpp
    metrics/report.cpp
    metrics/report_writer.cpp
)

regimeflow_target_public_include(regimeflow_metrics)
regimeflow_enable_windows_exports(regimeflow_metrics)

target_link_libraries(regimeflow_metrics
    PUBLIC
        regimeflow_common
)

add_library(regimeflow_regime
    regime/constant_detector.cpp
    regime/ensemble.cpp
    regime/features.cpp
    regime/hmm.cpp
    regime/regime_factory.cpp
    regime/state_manager.cpp
)

regimeflow_target_public_include(regimeflow_regime)
regimeflow_enable_windows_exports(regimeflow_regime)

target_link_libraries(regimeflow_regime
    PUBLIC
        regimeflow_common
        regimeflow_plugins
)

add_library(regimeflow_plugins
    plugins/hooks.cpp
    plugins/registry.cpp
)

regimeflow_target_public_include(regimeflow_plugins)
regimeflow_enable_windows_exports(regimeflow_plugins)

if(UNIX AND NOT APPLE)
    target_link_libraries(regimeflow_plugins PUBLIC ${CMAKE_DL_LIBS})
endif()

add_library(regimeflow_walkforward
    walkforward/optimizer.cpp
)

regimeflow_target_public_include(regimeflow_walkforward)
regimeflow_enable_windows_exports(regimeflow_walkforward)

target_link_libraries(regimeflow_walkforward
    PUBLIC
        regimeflow_common
        regimeflow_metrics
        regimeflow_engine
)

set(REGIMEFLOW_LIVE_SOURCES
    live/alpaca_adapter.cpp
    live/audit_log.cpp
    live/binance_adapter.cpp
    live/event_bus.cpp
    live/live_engine.cpp
    live/live_order_manager.cpp
    live/mq_adapter.cpp
    live/mq_codec.cpp
    live/secret_hygiene.cpp
    live/types.cpp
)

if(ENABLE_IBAPI)
    list(APPEND REGIMEFLOW_LIVE_SOURCES live/ib_adapter.cpp)
endif()

add_library(regimeflow_live ${REGIMEFLOW_LIVE_SOURCES})

regimeflow_target_public_include(regimeflow_live)
regimeflow_enable_windows_exports(regimeflow_live)

target_link_libraries(regimeflow_live
    PUBLIC
        regimeflow_common
        regimeflow_engine
        regimeflow_metrics
        regimeflow_strategy
        regimeflow_risk
        regimeflow_regime
        regimeflow_data
)

if(WIN32)
    target_link_libraries(regimeflow_live PRIVATE Psapi)
    target_compile_definitions(regimeflow_live PRIVATE _WIN32_WINNT=0x0A00 NOMINMAX)
endif()

if(ENABLE_IBAPI)
    target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_ENABLE_IBAPI)
endif()

if(ENABLE_OPENSSL)
find_package(OpenSSL QUIET)
if(OpenSSL_FOUND)
    target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_OPENSSL)
    target_link_libraries(regimeflow_live PRIVATE OpenSSL::SSL OpenSSL::Crypto)
endif()
endif()

if(ENABLE_ZMQ OR ENABLE_REDIS OR ENABLE_KAFKA)
    find_package(PkgConfig QUIET)
    if(APPLE)
        list(APPEND CMAKE_PREFIX_PATH "/opt/homebrew")
        if(PKG_CONFIG_FOUND)
            list(APPEND PKG_CONFIG_PATH "/opt/homebrew/lib/pkgconfig" "/opt/homebrew/share/pkgconfig")
        endif()
    endif()
    if(WIN32)
        set(_vcpkg_lib_suffix "")
        if(CMAKE_BUILD_TYPE STREQUAL "Debug")
            set(_vcpkg_lib_suffix "/debug")
        endif()
        if(DEFINED VCPKG_INSTALLED_DIR)
            list(APPEND _vcpkg_lib_hints "${VCPKG_INSTALLED_DIR}/x64-windows${_vcpkg_lib_suffix}/lib")
            list(APPEND _vcpkg_inc_hints "${VCPKG_INSTALLED_DIR}/x64-windows/include")
        endif()
    endif()
    if(ENABLE_ZMQ)
        if(WIN32)
            # On Windows, prefer vcpkg CMake config targets to avoid bare library names.
            find_package(cppzmq CONFIG REQUIRED)
            target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_ZMQ)
            target_link_libraries(regimeflow_live PRIVATE cppzmq)
        else()
            if(PKG_CONFIG_FOUND)
                pkg_check_modules(ZMQ libzmq)
            endif()
            if(ZMQ_FOUND)
                target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_ZMQ)
                target_include_directories(regimeflow_live PRIVATE ${ZMQ_INCLUDE_DIRS})
                target_link_libraries(regimeflow_live PRIVATE ${ZMQ_LIBRARIES})
            else()
                find_library(ZMQ_LIBRARY NAMES libzmq zmq
                    HINTS ${_vcpkg_lib_hints}
                )
                if(ZMQ_LIBRARY)
                    target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_ZMQ)
                    target_link_libraries(regimeflow_live PRIVATE ${ZMQ_LIBRARY})
                    if(_vcpkg_inc_hints)
                        target_include_directories(regimeflow_live PRIVATE ${_vcpkg_inc_hints})
                    endif()
                endif()
            endif()
        endif()
    endif()

    if(ENABLE_REDIS)
        if(PKG_CONFIG_FOUND)
            pkg_check_modules(REDIS IMPORTED_TARGET hiredis)
        endif()
        if(REDIS_FOUND)
            target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_REDIS)
            if(TARGET PkgConfig::REDIS)
                target_link_libraries(regimeflow_live PRIVATE PkgConfig::REDIS)
            else()
                target_include_directories(regimeflow_live PRIVATE ${REDIS_INCLUDE_DIRS})
                target_link_directories(regimeflow_live PRIVATE ${REDIS_LIBRARY_DIRS})
                target_link_libraries(regimeflow_live PRIVATE ${REDIS_LIBRARIES})
            endif()
        else()
            find_library(REDIS_LIBRARY hiredis
                HINTS /opt/homebrew/lib /usr/local/lib
            )
            if(REDIS_LIBRARY)
                target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_REDIS)
                target_link_libraries(regimeflow_live PRIVATE ${REDIS_LIBRARY})
            elseif(REGIMEFLOW_FETCH_DEPS)
                include(FetchContent)
                FetchContent_Declare(
                    hiredis
                    GIT_REPOSITORY https://github.com/redis/hiredis.git
                    GIT_TAG v1.2.0
                )
                FetchContent_MakeAvailable(hiredis)
                if(TARGET hiredis)
                    set_target_properties(hiredis PROPERTIES SYSTEM ON)
                    # hiredis headers are in the repo root; create a shim include dir
                    # so <hiredis/hiredis.h> resolves when building from source.
                    set(HIREDIS_SHIM_DIR "${hiredis_BINARY_DIR}/include")
                    file(MAKE_DIRECTORY "${HIREDIS_SHIM_DIR}/hiredis")
                    file(GLOB HIREDIS_HEADERS "${hiredis_SOURCE_DIR}/*.h")
                    file(COPY ${HIREDIS_HEADERS} DESTINATION "${HIREDIS_SHIM_DIR}/hiredis")
                    if(EXISTS "${hiredis_SOURCE_DIR}/adapters")
                        file(COPY "${hiredis_SOURCE_DIR}/adapters" DESTINATION "${HIREDIS_SHIM_DIR}/hiredis")
                    endif()
                    target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_REDIS)
                    target_link_libraries(regimeflow_live PRIVATE hiredis)
                    target_include_directories(regimeflow_live SYSTEM PRIVATE "${HIREDIS_SHIM_DIR}")
                endif()
            endif()
        endif()
    endif()

    if(ENABLE_KAFKA)
        if(WIN32)
            # On Windows, use the vcpkg CMake target to get the correct lib path.
            find_package(RdKafka CONFIG REQUIRED)
            target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_KAFKA)
            target_link_libraries(regimeflow_live PRIVATE RdKafka::rdkafka)
        else()
            if(PKG_CONFIG_FOUND)
                pkg_check_modules(KAFKA rdkafka)
            endif()
            if(KAFKA_FOUND)
                target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_KAFKA)
                target_include_directories(regimeflow_live PRIVATE ${KAFKA_INCLUDE_DIRS})
                target_link_libraries(regimeflow_live PRIVATE ${KAFKA_LIBRARIES})
            else()
                find_library(KAFKA_LIBRARY NAMES rdkafka
                    HINTS ${_vcpkg_lib_hints}
                )
                if(KAFKA_LIBRARY)
                    target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_KAFKA)
                    target_link_libraries(regimeflow_live PRIVATE ${KAFKA_LIBRARY})
                    if(_vcpkg_inc_hints)
                        target_include_directories(regimeflow_live PRIVATE ${_vcpkg_inc_hints})
                    endif()
                endif()
            endif()
        endif()
    endif()
endif()

if(ENABLE_IBAPI AND TARGET ibapi)
    target_link_libraries(regimeflow_live PUBLIC ibapi)
    target_include_directories(regimeflow_live PRIVATE ${IBAPI_ROOT})
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang")
    set_source_files_properties(
        ${CMAKE_CURRENT_SOURCE_DIR}/live/mq_adapter.cpp
        PROPERTIES COMPILE_OPTIONS "-Wno-c99-extensions"
    )
endif()

if(CURL_FOUND)
    target_compile_definitions(regimeflow_live PRIVATE REGIMEFLOW_USE_CURL)
    if(TARGET CURL::libcurl)
        target_link_libraries(regimeflow_live PRIVATE CURL::libcurl)
    else()
        target_include_directories(regimeflow_live PRIVATE ${CURL_INCLUDE_DIRS})
        target_link_libraries(regimeflow_live PRIVATE ${CURL_LIBRARIES})
    endif()
endif()

add_executable(regimeflow_live_cli tools/live_main.cpp)
target_link_libraries(regimeflow_live_cli PRIVATE regimeflow_live)
set_target_properties(regimeflow_live_cli PROPERTIES OUTPUT_NAME regimeflow_live)

add_executable(regimeflow_live_validate tools/live_validation_main.cpp)
target_link_libraries(regimeflow_live_validate PRIVATE regimeflow_live)

add_executable(regimeflow_parity_check tools/parity_check_main.cpp)
target_link_libraries(regimeflow_parity_check PRIVATE regimeflow_engine regimeflow_common)

add_executable(regimeflow_backtest_controls_demo tools/backtest_controls_demo.cpp)
target_link_libraries(regimeflow_backtest_controls_demo PRIVATE
    regimeflow_engine
    regimeflow_strategy
    regimeflow_execution
    regimeflow_data
    regimeflow_risk
    regimeflow_metrics
    regimeflow_regime
    regimeflow_plugins
    regimeflow_common
)

add_executable(regimeflow_strategy_tester tools/strategy_tester_main.cpp)
target_link_libraries(regimeflow_strategy_tester PRIVATE
    regimeflow_engine
    regimeflow_strategy
    regimeflow_execution
    regimeflow_data
    regimeflow_risk
    regimeflow_metrics
    regimeflow_regime
    regimeflow_plugins
    regimeflow_common
)
