# Desktop simulator for the thermostat UI. Not part of the ESP-IDF build --
# `idf.py build` never looks in here, and this never builds firmware sources
# that touch hardware.
#
#   cmake -S sim -B sim/build -G Ninja && cmake --build sim/build
#
# See sim/README.md.

cmake_minimum_required(VERSION 3.16)
project(thermostat_sim C)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(FW_ROOT ${CMAKE_CURRENT_LIST_DIR}/..)
set(LVGL_DIR ${FW_ROOT}/managed_components/lvgl__lvgl)

# LVGL is pulled in by the IDF component manager, so it lives in a gitignored
# directory that only exists after an IDF build. Using it anyway -- rather than
# fetching a second copy -- guarantees the simulator and the firmware render
# with the identical LVGL version. A simulator on a different version is a
# simulator that lies.
if(NOT EXISTS ${LVGL_DIR}/lvgl.h)
    message(FATAL_ERROR
        "LVGL not found at ${LVGL_DIR}\n"
        "It is fetched by the ESP-IDF component manager. Run once:\n"
        "    . ~/esp/esp-idf/export.sh && idf.py reconfigure")
endif()

# Nothing here uses LVGL's bundled demos or examples, and they add real build
# time. ThorVG is a C++ vector engine we do not use either.
set(CONFIG_LV_BUILD_DEMOS OFF CACHE BOOL "" FORCE)
set(CONFIG_LV_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(CONFIG_LV_USE_THORVG_INTERNAL OFF CACHE BOOL "" FORCE)

# LVGL's desktop CMake picks up lv_conf.h from CMAKE_SOURCE_DIR, which is this
# directory.
add_subdirectory(${LVGL_DIR} ${CMAKE_BINARY_DIR}/lvgl)

find_package(SDL2 REQUIRED)

# cJSON comes from the ESP-IDF tree rather than the host's libcjson, so the
# simulator parses Home Assistant replies with the exact same parser the
# firmware uses. IDF_PATH is only needed for this one directory -- the rest of
# the simulator builds with no ESP-IDF environment at all.
if(DEFINED ENV{IDF_PATH})
    set(IDF_ROOT $ENV{IDF_PATH})
else()
    set(IDF_ROOT $ENV{HOME}/esp/esp-idf)
endif()
set(CJSON_DIR ${IDF_ROOT}/components/json/cJSON)

if(NOT EXISTS ${CJSON_DIR}/cJSON.c)
    message(FATAL_ERROR
        "cJSON not found at ${CJSON_DIR}\n"
        "Set IDF_PATH, or install ESP-IDF to ~/esp/esp-idf.")
endif()

add_executable(thermostat_sim
    sim_main.c
    lvgl_port_sim.c
    compat/esp_compat.c

    # The point of the exercise: real firmware sources, compiled unmodified.
    # Anything added here must stay free of hardware access -- drivers and
    # HTTP transport stay on the device side.
    ${FW_ROOT}/main/ui/ui_manager.c
    ${FW_ROOT}/main/ui/icon_font.c
    ${FW_ROOT}/main/api/ha_data.c

    ${CJSON_DIR}/cJSON.c
)

target_include_directories(thermostat_sim PRIVATE
    ${CMAKE_CURRENT_LIST_DIR}
    ${CMAKE_CURRENT_LIST_DIR}/compat   # ESP-IDF header stand-ins
    ${FW_ROOT}/main/ui                 # ui_manager.h, lvgl_port.h
    ${FW_ROOT}/main/api                # ha_data.h, ha_config.h, ha_template.h
    ${CJSON_DIR}
    ${LVGL_DIR}/src/libs/lodepng       # PNG encoder for --png mode
    ${SDL2_INCLUDE_DIRS}
)

# SDL2_LIBRARIES can carry trailing whitespace from sdl2-config, which makes
# the link line fail in confusing ways.
string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)

target_link_libraries(thermostat_sim PRIVATE lvgl ${SDL2_LIBRARIES} m pthread)

target_compile_options(thermostat_sim PRIVATE -Wall -Wextra -Wno-unused-parameter)
