cmake_minimum_required(VERSION 3.20)
project(MarioLuigiSuperstarSagaRecomp C CXX)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Shared dependencies are read-only; all compilation output stays in build/.
set(GBARECOMP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/gbarecomp" CACHE PATH "Pinned project framework")
if(NOT EXISTS "${GBARECOMP_ROOT}/CMakeLists.txt")
    if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/reference/gbarecomp/CMakeLists.txt")
        set(GBARECOMP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/reference/gbarecomp" CACHE PATH "Pinned project framework" FORCE)
    elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../gbarecomp-main/CMakeLists.txt")
        set(GBARECOMP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../gbarecomp-main" CACHE PATH "Pinned project framework" FORCE)
    endif()
endif()

set(GBARECOMP_GENERATED_BIOS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated/bios" CACHE PATH "Local BIOS translation")
set(GBARECOMP_TOMLPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.deps/tomlplusplus" CACHE PATH "Pinned toml++ headers")
set(RECOMP_UI_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/recomp-ui" CACHE PATH "Pinned player launcher")
set(GBARECOMP_SELFHEAL_RECOMPILE_DEFAULT OFF CACHE BOOL "Preview needs no runtime compiler" FORCE)
set(GBARECOMP_COMPILER_CACHE OFF CACHE STRING "Keep compilation output inside this project")

add_subdirectory("${GBARECOMP_ROOT}" framework EXCLUDE_FROM_ALL)
get_target_property(RUNTIME_DEFINES gbarecomp_runtime COMPILE_DEFINITIONS)
list(FILTER RUNTIME_DEFINES EXCLUDE REGEX "^GBARECOMP_SRC_DIR=")
set_property(TARGET gbarecomp_runtime PROPERTY COMPILE_DEFINITIONS ${RUNTIME_DEFINES} GBARECOMP_SRC_DIR="gbarecomp")

if(EXISTS "${GBARECOMP_GENERATED_BIOS_DIR}/codegen_tail_macros.h")
    if(MSVC)
        target_compile_options(gbarecomp_runtime PRIVATE
            "/FI${GBARECOMP_GENERATED_BIOS_DIR}/codegen_tail_macros.h")
    else()
        target_compile_options(gbarecomp_runtime PRIVATE
            "-include" "${GBARECOMP_GENERATED_BIOS_DIR}/codegen_tail_macros.h")
    endif()
endif()

if(NOT GBARECOMP_SDL2_OK)
    # The framework sets this in its own directory scope. Check the target too.
    get_target_property(RUNTIME_DEFINES gbarecomp_runtime COMPILE_DEFINITIONS)
    if(NOT "GBARECOMP_HAVE_SDL2" IN_LIST RUNTIME_DEFINES)
        message(FATAL_ERROR "A real SDL2 backend is required for this preview")
    endif()
endif()

if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/generated/cart/dispatch_table.cpp")
    file(GLOB CART_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/generated/cart/*.cpp")
    add_executable(MarioLuigiSuperstarSagaRecomp src/main.cpp ${CART_SOURCES})
    target_link_gbarecomp_runtime_stack(MarioLuigiSuperstarSagaRecomp)
    if(MINGW)
        target_link_options(MarioLuigiSuperstarSagaRecomp PRIVATE "-Wl,--stack,67108864")
    endif()
    set(SHARDS ${CART_SOURCES})
    list(FILTER SHARDS INCLUDE REGEX "/recompiled_[0-9]+\\.cpp$")
    if(MSVC)
        set_source_files_properties(${SHARDS} PROPERTIES COMPILE_OPTIONS "/O1;/FI${GBARECOMP_GENERATED_BIOS_DIR}/codegen_tail_macros.h")
        target_compile_options(MarioLuigiSuperstarSagaRecomp PRIVATE "/FI${GBARECOMP_GENERATED_BIOS_DIR}/codegen_tail_macros.h")
    else()
        set_source_files_properties(${SHARDS} PROPERTIES COMPILE_OPTIONS "-O1;-g0;-include;${GBARECOMP_GENERATED_BIOS_DIR}/codegen_tail_macros.h")
        target_compile_options(MarioLuigiSuperstarSagaRecomp PRIVATE "-include" "${GBARECOMP_GENERATED_BIOS_DIR}/codegen_tail_macros.h")
    endif()

    include("${RECOMP_UI_ROOT}/recomp_ui.cmake")
    add_library(game_launcher_ui STATIC src/game_launcher_boot.cpp)
    target_include_directories(game_launcher_ui PRIVATE "${GBARECOMP_ROOT}/src/runtime" "${GBARECOMP_ROOT}/src/gba" ${SDL2_INCLUDE_DIR})
    recomp_target_launcher_ui(game_launcher_ui CONSOLE gba)
    target_link_libraries(game_launcher_ui PUBLIC ${SDL2_LIBRARY})
    target_link_libraries(MarioLuigiSuperstarSagaRecomp PRIVATE game_launcher_ui)
    recomp_stage_launcher_assets(MarioLuigiSuperstarSagaRecomp CONSOLE gba)

    add_executable(launcher_contract EXCLUDE_FROM_ALL tests/launcher_contract.cpp)
    target_compile_definitions(launcher_contract PRIVATE RECOMP_LAUNCHER)
    target_include_directories(launcher_contract PRIVATE "${GBARECOMP_ROOT}/src/runtime" "${RECOMP_UI_ROOT}/src" "${RECOMP_UI_ROOT}/src/common")
    target_link_libraries(launcher_contract PRIVATE game_launcher_ui gbarecomp_gba)

    gbarecomp_stage_mingw_runtime(MarioLuigiSuperstarSagaRecomp)
    if(SDL2_DLL)
        add_custom_command(TARGET MarioLuigiSuperstarSagaRecomp POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SDL2_DLL}"
            "$<TARGET_FILE_DIR:MarioLuigiSuperstarSagaRecomp>/SDL2.dll")
    endif()
endif()
