cmake_minimum_required(VERSION 3.16)
project(CpdController)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# ── Dezyne paths ─────────────────────────────────────────────────────────────
set(DZN_INSTALL_DIR "/Users/karkob/src/dezyne-monorepo/packages/distribution/build")
# Use the top-level <installDir>/dzn launcher, NOT bin/dzn — the launcher
# sets GUILE_LOAD_PATH / DZN_PREFIX / GUILE_LOAD_COMPILED_PATH before
# exec'ing the bare bin/dzn shim. Without it, Guile can't resolve the
# (dzn script) module and dies with "Wrong type argument in position 1
# (expecting module): #f".
set(DZN_TOOL        "/Users/karkob/src/dezyne-monorepo/packages/distribution/build/dzn")
set(DZN_RUNTIME_DIR "/Users/karkob/src/dezyne-monorepo/packages/distribution/build/runtime/c++")

# ── Directories ──────────────────────────────────────────────────────────────
set(MODELS_DIR    "/Users/karkob/src/child-presence-detection-demo/Models")
set(GENERATED_DIR "/Users/karkob/src/child-presence-detection-demo/build/generated")
set(SRC_DIR       "/Users/karkob/src/child-presence-detection-demo/src")

file(MAKE_DIRECTORY ${GENERATED_DIR})

# ── Stage 1: generate C++ from .dzn models ───────────────────────────────────
file(GLOB_RECURSE DEZYNE_MODELS "${MODELS_DIR}/*.dzn")

set(DEZYNE_CODE_FILES)
foreach(DZN_FILE ${DEZYNE_MODELS})
    get_filename_component(MODEL_STEM "${DZN_FILE}" NAME_WE)
    set(MODEL_HH "${GENERATED_DIR}/${MODEL_STEM}.hh")
    set(MODEL_CC "${GENERATED_DIR}/${MODEL_STEM}.cc")

    add_custom_command(
        OUTPUT  "${MODEL_HH}" "${MODEL_CC}"
        COMMAND "${DZN_TOOL}" code
    "-I" "/Users/karkob/src/child-presence-detection-demo/Models"
                "${DZN_FILE}"
        WORKING_DIRECTORY "${GENERATED_DIR}"
        DEPENDS "${DZN_FILE}"
        COMMENT "dzn code ${MODEL_STEM}"
    )
    list(APPEND DEZYNE_CODE_FILES "${MODEL_HH}" "${MODEL_CC}")
endforeach()

add_custom_target(generate_dezyne_code ALL DEPENDS ${DEZYNE_CODE_FILES})

# ── Stage 1.5: write forwarding headers ──────────────────────────────────────
add_custom_command(
    TARGET generate_dezyne_code POST_BUILD
    COMMAND ${CMAKE_COMMAND}
        "-DGENERATED_DIR=${GENERATED_DIR}"
        "-DSRC_DIR=${SRC_DIR}"
        -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_forwarding_headers.cmake"
    COMMENT "Writing forwarding headers"
)

# ── Stage 2: compile ──────────────────────────────────────────────────────────
# Dezyne C++ runtime (compiled as a static library)
file(GLOB DZN_RUNTIME_SOURCES "${DZN_RUNTIME_DIR}/*.cc")
add_library(DezyneRuntime STATIC ${DZN_RUNTIME_SOURCES})
target_include_directories(DezyneRuntime PUBLIC "${DZN_RUNTIME_DIR}")

# Hand-written sources
file(GLOB_RECURSE HAND_WRITTEN_SOURCES "${SRC_DIR}/*.cc" "${SRC_DIR}/*.cpp")

# Generated sources (collected after code-gen target runs)
file(GLOB_RECURSE GENERATED_SOURCES "${GENERATED_DIR}/*.cc")

add_executable(${PROJECT_NAME}
    main.cpp
    ${HAND_WRITTEN_SOURCES}
    ${GENERATED_SOURCES}
)

add_dependencies(${PROJECT_NAME} generate_dezyne_code)

target_include_directories(${PROJECT_NAME} PRIVATE
    "${GENERATED_DIR}"
    "${SRC_DIR}"
    "${DZN_RUNTIME_DIR}"
)

target_link_libraries(${PROJECT_NAME} PRIVATE DezyneRuntime)
