cmake_minimum_required(VERSION 3.18.4)

project(shedskin_products LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)

# -----------------------------------------------------------------------------
# options

option(DEBUG "Enable debug output" OFF)

option(BUILD_EXECUTABLE "Build executable" ON)
option(BUILD_EXTENSION "Build python extension" OFF)
option(BUILD_TEST "Build test" ON)

option(ENABLE_SPM "Enable shedskin dependency management" OFF)
option(ENABLE_FETCH_CONTENT "Enable FetchContent for dependency mgmt" OFF)
option(ENABLE_LOCAL_DEPS "Enable local dependency management" OFF)

# -----------------------------------------------------------------------------
# find python executable and shedskin package path

find_package(Python REQUIRED COMPONENTS Interpreter Development)
if(DEBUG)
    message("python:" ${Python_EXECUTABLE})
    message("python_include:" ${Python_INCLUDE_DIRS})
endif()

# -----------------------------------------------------------------------------
# find shedskin package path

if(NOT DEFINED SHEDSKIN)
    execute_process(
        COMMAND ${Python_EXECUTABLE} -c "from shedskin import pkg_path; pkg_path()"
        OUTPUT_VARIABLE SHEDSKIN_PATH
        COMMAND_ERROR_IS_FATAL ANY
    )
    set(SHEDSKIN ${SHEDSKIN_PATH} CACHE PATH "setting path to shedskin pkg" FORCE)
endif()

set(SHEDSKIN_LIB ${SHEDSKIN}/lib)

include_directories(
    ${SHEDSKIN_LIB}
)

# -----------------------------------------------------------------------------
# includes (must be before dependency mgmt to find shedskin_deps module)
list(APPEND CMAKE_MODULE_PATH "${SHEDSKIN}/resources/cmake")
include(utils)
include(fn_add_shedskin_product)

# -----------------------------------------------------------------------------
# dependency mgmt solutions

if(ENABLE_SPM)
    set(SPM_DEPS ${CMAKE_BINARY_DIR}/deps)
    set(SPM_LIB_DIRS ${SPM_DEPS}/lib)
    set(SPM_INCLUDE_DIRS ${SPM_DEPS}/include)

elseif(ENABLE_FETCH_CONTENT)
    include(shedskin_deps)
    set(FETCHCONTENT_INCLUDE_DIR ${SHEDSKIN_DEP_INCLUDE_DIR})
    set(FETCHCONTENT_PCRE2_INCLUDE_DIR ${SHEDSKIN_PCRE2_INCLUDE_DIR})

elseif(ENABLE_LOCAL_DEPS)
    if(NOT DEFINED LOCAL_DEPS_DIR)
        message(FATAL_ERROR "LOCAL_DEPS_DIR must be defined when ENABLE_LOCAL_DEPS is ON")
    endif()
    message(STATUS "LOCAL_DEPS_DIR: ${LOCAL_DEPS_DIR}")
    set(LOCAL_DEPS_LIB_DIRS ${LOCAL_DEPS_DIR}/lib)
    set(LOCAL_DEPS_INCLUDE_DIRS ${LOCAL_DEPS_DIR}/include)
endif()

# -----------------------------------------------------------------------
# any 'test_*' folders are automatically treated as tests

if(BUILD_TEST)
    enable_testing()
    if (EXISTS ${PROJECT_SOURCE_DIR}/testdata)
        # copy test data to cmake 'build' folder
        file(COPY ${PROJECT_SOURCE_DIR}/testdata DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
    endif()

    # add_subdirectory(tests)
    file(GLOB test_dirs "test_*"
        LIST_DIRECTORIES true
    )

    foreach(testdir ${test_dirs})
        if(IS_DIRECTORY ${testdir})
            get_filename_component(testdir_name ${testdir} NAME_WLE)
            if (DEBUG)
                message("testdir_name:" ${testdir_name})
            endif()
            add_subdirectory(${testdir_name})
        endif()
    endforeach()
endif()


# -----------------------------------------------------------------------
# add subdirectories here

add_subdirectory(ac_encode)
add_subdirectory(adatron)
add_subdirectory(amaze)
add_subdirectory(ant)
add_subdirectory(astar) # ext
add_subdirectory(bh)
add_subdirectory(block)
add_subdirectory(brainfuck)
#add_subdirectory(c64) # loaders/__init__ not found.. works separately. probably because of extra subdir.
add_subdirectory(chaos)
add_subdirectory(chess)
add_subdirectory(chull)
add_subdirectory(circle) # ext
add_subdirectory(collatz)
add_subdirectory(dijkstra)
add_subdirectory(dijkstra2)
add_subdirectory(doom)
add_subdirectory(fysphun) # ext
add_subdirectory(genetic)
add_subdirectory(genetic2)
add_subdirectory(go)
add_subdirectory(gs)
add_subdirectory(hq2x)
add_subdirectory(kanoodle)
add_subdirectory(kmeanspp)
add_subdirectory(life)
add_subdirectory(linalg)
add_subdirectory(loop)
add_subdirectory(lz2)
add_subdirectory(mandelbrot)
add_subdirectory(mandelbrot2) # ext
add_subdirectory(mao)
add_subdirectory(mastermind) # nested ext
add_subdirectory(mastermind2)
add_subdirectory(minilight)
add_subdirectory(minpng)
add_subdirectory(mwmatching)
add_subdirectory(nbody)
add_subdirectory(neural1)
add_subdirectory(neural2)
add_subdirectory(oliva2)
add_subdirectory(othello)
add_subdirectory(othello2)
add_subdirectory(path_tracing)
add_subdirectory(pisang)
add_subdirectory(plcfrs)
add_subdirectory(pygasus) # ext no-bounds
add_subdirectory(pygmy)
add_subdirectory(pycsg)
add_subdirectory(pylife) # ext
add_subdirectory(pylot) # nested ext
add_subdirectory(pystone)
add_subdirectory(quameon) # deep exe
add_subdirectory(rdb)
add_subdirectory(richards)
add_subdirectory(rubik)
add_subdirectory(rubik2)
add_subdirectory(sat)
add_subdirectory(score4)
add_subdirectory(sieve)
add_subdirectory(softrender)
add_subdirectory(sokoban)
add_subdirectory(solitaire)
add_subdirectory(stereo) # ext
add_subdirectory(sudoku1)
add_subdirectory(sudoku2)
add_subdirectory(sudoku3)
add_subdirectory(sudoku4)
add_subdirectory(sudoku5)
add_subdirectory(sunfish)
add_subdirectory(tarsalzp)
add_subdirectory(tictactoe)
add_subdirectory(timsort)
add_subdirectory(tonyjpegdecoder)
add_subdirectory(voronoi)
add_subdirectory(voronoi2)
add_subdirectory(yopyra)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
    ## select not working on macOS (win?)
    ## windows not yet tested.
    add_subdirectory(webserver)
#    add_subdirectory(msp_ss) # requires serial
#    add_subdirectory(rsync) # requires hashlib (openssl)
#    add_subdirectory(sha) # requires hashlib (openssl)
endif()
