cmake_minimum_required(VERSION 3.10)

if(POLICY CMP0079)
    cmake_policy(SET CMP0079 NEW)
endif()

project(has_project_host LANGUAGES C)

# 当前宿主工程通过 add_subdirectory(has_platform) 的方式接入平台子仓库，
# 以模拟真实项目拉取 has_platform 子仓库后的编译场景。

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

add_library(has_project_warnings INTERFACE)

target_compile_options(has_project_warnings
    INTERFACE
        $<$<COMPILE_LANG_AND_ID:C,GNU,Clang,AppleClang>:
            -Wall
            -Wextra
            # -Wpedantic
            -Wformat=2
            -Wundef
            -Wshadow
            -Wpointer-arith
            -Wwrite-strings
            -Wstrict-prototypes
            # -Wmissing-prototypes
            -Werror=implicit-function-declaration
        >
)

# 宿主工程选择如何集成 has_platform：
# static: 链接静态库
# shared: 链接动态库
# embed : 直接把 has_platform 对象文件并入宿主目标
set(HAS_PLATFORM_LINK_MODE "static" CACHE STRING
    "How the host project integrates has_platform: static, shared or embed")
set_property(CACHE HAS_PLATFORM_LINK_MODE PROPERTY STRINGS static shared embed)

if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/has_project/has_platform_config.h")
    message(FATAL_ERROR
        "Missing has_project/has_platform_config.h. "
        "The host project must provide has_platform_config.h.")
endif()

# 宿主工程显式告诉 has_platform 去 has_project/ 里查找配置头，
# 这样可以模拟外部项目拉取子仓库后的真实接入方式。
set(HAS_PLATFORM_CONFIG_DIR "${CMAKE_CURRENT_LIST_DIR}/has_project" CACHE PATH
    "Directory that provides has_platform_config.h for has_platform" FORCE)

# 根据宿主工程的接入方式控制 has_platform 子仓库输出何种目标。
if(HAS_PLATFORM_LINK_MODE STREQUAL "static")
    set(HAS_PLATFORM_BUILD_STATIC ON CACHE BOOL "" FORCE)
    set(HAS_PLATFORM_BUILD_SHARED OFF CACHE BOOL "" FORCE)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "shared")
    set(HAS_PLATFORM_BUILD_STATIC OFF CACHE BOOL "" FORCE)
    set(HAS_PLATFORM_BUILD_SHARED ON CACHE BOOL "" FORCE)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "embed")
    set(HAS_PLATFORM_BUILD_STATIC OFF CACHE BOOL "" FORCE)
    set(HAS_PLATFORM_BUILD_SHARED OFF CACHE BOOL "" FORCE)
else()
    message(FATAL_ERROR
        "Unsupported HAS_PLATFORM_LINK_MODE='${HAS_PLATFORM_LINK_MODE}'. "
        "Expected one of: static, shared, embed")
endif()

add_subdirectory(has_platform)
target_link_libraries(has_platform_obj PRIVATE has_project_warnings)

# 宿主工程业务源码。保持 has_project 现有目录结构不变。
file(GLOB HOST_APP_SOURCES CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/*.c"
    "${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/gui/*.c"
    # "${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/sensor/*.c"
    "${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/wifi/*.c"
    "${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/acm/*.c"
)

file(GLOB HOST_DRIVER_SOURCES CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_LIST_DIR}/has_project/has_driver/v851/*.c"
)

set(HOST_PROJECT_SOURCES
    ${HOST_APP_SOURCES}
    ${HOST_DRIVER_SOURCES}
)

if(HOST_PROJECT_SOURCES STREQUAL "")
    message(FATAL_ERROR "No host project sources were found under has_project/")
endif()

add_executable(test ${HOST_PROJECT_SOURCES})

target_compile_features(test PRIVATE c_std_11)
target_link_libraries(test PRIVATE has_project_warnings)

# 宿主工程根据选择的模式链接或嵌入 has_platform。
if(HAS_PLATFORM_LINK_MODE STREQUAL "static")
    target_link_libraries(test PRIVATE has_platform::static)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "shared")
    target_link_libraries(test PRIVATE has_platform::shared)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "embed")
    has_platform_embed_in_target(test)
endif()

# 将可执行文件输出到 build/ 根目录，便于脚本统一运行。
set_target_properties(test PROPERTIES
    OUTPUT_NAME test
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)

message(STATUS "HAS_PLATFORM_LINK_MODE = ${HAS_PLATFORM_LINK_MODE}")
