# ============================================================================
# Top-level CMakeLists.txt for the color_switcher Pico firmware project
# ============================================================================
# This file is intentionally kept thin: it orchestrates the build phases in
# the strict order CMake requires. All real configuration lives in the
# cmake_config/*.cmake fragments so each concern is isolated and easy to find.
#
# Build phase order (forced by the Pico SDK + CMake semantics):
#   1. project_config         - variables only, no side effects
#   2. mcu_config             - defines mcu_init / mcu_sdk_config / mcu_link_target
#   3. mcu_init()             - SDK bootstrap (MUST run before project())
#   4. project()              - declares the CMake project using project_config vars
#   5. mcu_sdk_config()       - pico_sdk_init() (MUST run after project())
#   6. sources_config         - collects PROJECT_SOURCES and PROJECT_INCLUDE_DIRS
#   7. add_executable()       - the actual firmware build target
#   8. mcu_link_target()      - target_link_libraries + stdio + UF2 output
# ============================================================================

# Require CMake 3.13 or newer. The Pico SDK uses features (like
# target_link_libraries on object libraries) that were added in 3.13,
# so older versions will fail to configure with cryptic errors.
cmake_minimum_required(VERSION 3.13)

# The real project root is one level above this file (this CMakeLists.txt
# lives in <project>/cmake/). Everything outside the build system - the
# src/ tree, the Dockerfile, etc. - is referenced via PROJECT_ROOT_DIR so
# we never have to sprinkle "../" paths throughout the cmake fragments.
get_filename_component(PROJECT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)

# Make cmake_config/ searchable so include(foo) resolves to
# cmake_config/foo.cmake without needing the full path each time.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_config)

# Phase 1 - project-wide variables (PROJECT_NAME, PROJECT_VERSION, etc.)
include(project_config)

# Phase 2 - MCU helper macros/functions (no side effects, just definitions)
include(mcu_config)

# Phase 3 - Pico SDK bootstrap. MUST run before project() so the ARM
# cross-compile toolchain is configured before CMake enables languages.
mcu_init()

# Phase 4 - declare the CMake project using variables from project_config.
# This triggers CMake to detect the (already-configured) cross compiler.
project(${PROJECT_NAME}
        VERSION   ${PROJECT_VERSION}
        LANGUAGES ${PROJECT_LANGUAGES})

# Phase 5 - register every Pico SDK library as a CMake target so we can
# pick which ones to link later. This does NOT pull libraries into the
# final binary - mcu_link_target() does that.
mcu_sdk_config()

# Phase 6 - collect the list of .c files and include directories into
# PROJECT_SOURCES and PROJECT_INCLUDE_DIRS variables.
include(sources_config)

# Phase 7 - declare the firmware executable and its include paths.
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE_DIRS})

# Phase 8 - link only the SDK libraries we actually use (pico_stdlib,
# hardware_uart), route stdio over USB-CDC, and emit the .uf2 firmware file.
mcu_link_target(${PROJECT_NAME})
