cmake_minimum_required(VERSION 3.10)
project(light_control_esp8266_tests)

# Set C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Add compile definitions
add_definitions(
    -DUNIT_TEST
    -DESP8266
    -DHIGH=1
    -DLOW=0
    -DOUTPUT=1
    -DINPUT=0
    -DARDUINO=100
    -DPWM_CONTROL
    -DBRI_CONTROL
    -DCCT_CONTROL
    -DPWM_MAX=1023
    -DPWM_FRQ=1000
    -DCCT_START=2700
    -DCCT_END=6500
    -DCCT_START_MIRED=370
    -DCCT_END_MIRED=153
    -DRECONNECT_MQTT_INTERVAL=3000
)

# Download and configure Google Test and ArduinoJson
include(FetchContent)

# Google Test
FetchContent_Declare(
    googletest
    URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

# ArduinoJson (real library instead of mock)
FetchContent_Declare(
    ArduinoJson
    GIT_REPOSITORY https://github.com/bblanchon/ArduinoJson.git
    GIT_TAG v7.0.4
)
FetchContent_MakeAvailable(ArduinoJson)

# Include directories (after FetchContent so variables are available)
include_directories(
    ${CMAKE_SOURCE_DIR}/test/mocks
    ${CMAKE_SOURCE_DIR}/test
    ${CMAKE_SOURCE_DIR}/lamp_ctrl2_esp8266
    ${CMAKE_SOURCE_DIR}/lamp_ctrl2_esp8266/base
    ${CMAKE_SOURCE_DIR}/lamp_ctrl2_esp8266/configs
    ${arduinojson_SOURCE_DIR}
)

# Mock library
add_library(mocks STATIC
    test/mocks/Arduino.cpp
    test/mocks/ESP8266WiFi.cpp
    test/mocks/FileData.cpp
    test/test_helpers.cpp
)
target_link_libraries(mocks ArduinoJson)

# Source library - unified source file that includes all .ino files
# Use OBJECT library to delay linking until the executable
add_library(lamp_sources OBJECT
    test/lamp_sources.cpp
)
target_link_libraries(lamp_sources mocks)

# Source library for WSRGB mode - same source but with WSRGB flag
add_library(lamp_sources_wsrgb OBJECT
    test/lamp_sources.cpp
)
target_compile_definitions(lamp_sources_wsrgb PRIVATE WSRGB WS_PIN=14 WS_NUM=8)
target_link_libraries(lamp_sources_wsrgb mocks)

# Test executables
add_executable(test_main_logic
    test/test_main_logic/test_main_logic.cpp
)
target_link_libraries(test_main_logic lamp_sources mocks ArduinoJson GTest::gtest_main)

add_executable(test_utils
    test/test_utils/test_utils.cpp
)
target_link_libraries(test_utils lamp_sources mocks ArduinoJson GTest::gtest_main)

add_executable(test_mqtt
    test/test_mqtt/test_mqtt.cpp
)
target_link_libraries(test_mqtt mocks ArduinoJson GTest::gtest_main)

add_executable(test_sensors
    test/test_sensors/test_sensors.cpp
)
target_link_libraries(test_sensors mocks ArduinoJson GTest::gtest_main)

# HA Integration tests - split by device type for better readability
add_executable(test_ha_integration
    test/test_ha_integration/test_ha_main.cpp
    test/test_ha_integration/test_ha_light.cpp
    test/test_ha_integration/test_ha_sensor.cpp
    test/test_ha_integration/test_ha_device_info.cpp
    test/test_ha_integration/test_ha_online_status.cpp
    test/test_ha_integration/test_ha_config.cpp
    test/test_ha_integration/test_ha_topic_consistency.cpp
)
target_link_libraries(test_ha_integration lamp_sources mocks ArduinoJson GTest::gtest)

# WSRGB send_config() integration tests - uses REAL code with WSRGB flag
# These tests should FAIL on the current branch (proving the bug exists)
# and PASS after the fix or on main branch (where WSRGB doesn't exist)
add_executable(test_wsrgb
    test/test_wsrgb/test_wsrgb_send_config.cpp
)
target_compile_definitions(test_wsrgb PRIVATE WSRGB WS_PIN=14 WS_NUM=8)
target_link_libraries(test_wsrgb lamp_sources_wsrgb mocks ArduinoJson GTest::gtest_main)

# IR Control tests
add_executable(test_ir_control
    test/test_ir_control/test_ir_control.cpp
)
target_link_libraries(test_ir_control mocks ArduinoJson GTest::gtest_main)

# Enable testing
enable_testing()

include(GoogleTest)
gtest_discover_tests(test_main_logic)
gtest_discover_tests(test_utils)
gtest_discover_tests(test_mqtt)
gtest_discover_tests(test_sensors)
gtest_discover_tests(test_ha_integration)
gtest_discover_tests(test_wsrgb)
gtest_discover_tests(test_ir_control)

# Custom target to run all tests
add_custom_target(check
    COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
    DEPENDS test_main_logic test_utils test_mqtt test_sensors test_ha_integration test_wsrgb test_ir_control
)

# Custom target to run tests with JUnit XML output for CI (GitLab, Jenkins, etc.)
# XML files are generated in the build directory for easy CI integration
add_custom_target(check-xml
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/test-results
    COMMAND $<TARGET_FILE:test_main_logic> --gtest_output=xml:${CMAKE_BINARY_DIR}/test-results/test_main_logic.xml
    COMMAND $<TARGET_FILE:test_utils> --gtest_output=xml:${CMAKE_BINARY_DIR}/test-results/test_utils.xml
    COMMAND $<TARGET_FILE:test_mqtt> --gtest_output=xml:${CMAKE_BINARY_DIR}/test-results/test_mqtt.xml
    COMMAND $<TARGET_FILE:test_sensors> --gtest_output=xml:${CMAKE_BINARY_DIR}/test-results/test_sensors.xml
    COMMAND $<TARGET_FILE:test_ha_integration> --gtest_output=xml:${CMAKE_BINARY_DIR}/test-results/test_ha_integration.xml
    COMMAND $<TARGET_FILE:test_wsrgb> --gtest_output=xml:${CMAKE_BINARY_DIR}/test-results/test_wsrgb.xml
    DEPENDS test_main_logic test_utils test_mqtt test_sensors test_ha_integration test_wsrgb
    COMMENT "Running tests with JUnit XML output for CI..."
)
