#
#   Copyright (c) 2023 Project CHIP Authors
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#

#
#   @file
#     CMake file defining to setup and build the Matter library
#     and other optional libraries like unit tests.
#     Matter headers and libraries are exposed to the application 
#     as a specific interface target.
#     Since Matter doesn't provide native CMake support, ExternalProject
#     module is used to build the required artifacts with GN meta-build
#     system.
#

# ==============================================================================
# Validate paths
# ==============================================================================
if (NOT GN_ROOT_TARGET)
    message(FATAL_ERROR "GN_ROOT_TARGET not defined. Please provide the path to your Matter GN project.")
endif()

if (NOT CHIP_ROOT)
    get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../.. REALPATH)
endif()

# ==============================================================================
# Find required programs
# ==============================================================================
find_package(Python3 REQUIRED)
find_program(GN_EXECUTABLE gn REQUIRED)

# Parse the 'gn --version' output to find the installed version.
set(MIN_GN_VERSION 1851)
execute_process(
    COMMAND ${GN_EXECUTABLE} --version
    OUTPUT_VARIABLE GN_VERSION
    COMMAND_ERROR_IS_FATAL ANY
)
if (GN_VERSION VERSION_LESS MIN_GN_VERSION)
    message(FATAL_ERROR "Found unsupported version of gn: ${MIN_GN_VERSION}+ is required")
endif()

# ==============================================================================
# Macros
# ==============================================================================
# Setup and build the Matter library and other optional libraries like unit tests.
# Expose Matter headers & libraries to the application as specific 
# interface target.
# [Args]:
#   target - interface target name
# Available options are:
#   LIB_SHELL       Build and add Matter shell library
#   LIB_PW_RPC      Build and add Matter PW RPC library
#   LIB_TESTS       Build and add Matter unit tests library
#   DEVICE_INFO_EXAMPLE_PROVIDER Add example device info provider support
#
#   GN_DEPENDENCIES List of targets that should be built before Matter GN project
macro(matter_build target)
    set(options)
    set(oneValueArgs
        LIB_TESTS 
        LIB_SHELL 
        LIB_PW_RPC
        DEVICE_INFO_EXAMPLE_PROVIDER
    )
    set(multiValueArgs GN_DEPENDENCIES)
    
    cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    set(MATTER_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib)

    # Prepare Matter libraries that the application should be linked with
    set(MATTER_LIBRARIES -lCHIP)

    if (ARG_LIB_SHELL)
        list(APPEND MATTER_LIBRARIES -lCHIPShell)
    endif()

    if (ARG_LIB_PW_RPC)
        list(APPEND MATTER_LIBRARIES -lPwRpc)
    endif()

    if (ARG_DEVICE_INFO_EXAMPLE_PROVIDER)
        list(APPEND MATTER_LIBRARIES -lMatterDeviceInfoProviderExample)
    endif()

    list(TRANSFORM MATTER_LIBRARIES REPLACE
        "-l(.*)"
        "${MATTER_LIB_DIR}/lib\\1.a"
    )

    # ==============================================================================
    # Define 'chip-gn' target that builds CHIP library(ies) with GN build system
    # ==============================================================================
    ExternalProject_Add(
        chip-gn
        PREFIX                  ${CMAKE_CURRENT_BINARY_DIR}
        SOURCE_DIR              ${CHIP_ROOT}
        BINARY_DIR              ${CMAKE_CURRENT_BINARY_DIR}
        CONFIGURE_COMMAND       ""
        CONFIGURE_HANDLED_BY_BUILD TRUE
        BUILD_COMMAND           ${CMAKE_COMMAND} -E echo "Starting Matter library build in ${CMAKE_CURRENT_BINARY_DIR}"
        COMMAND                 ${Python3_EXECUTABLE} ${CHIP_ROOT}/config/common/cmake/make_gn_args.py @args.tmp > args.gn.tmp
        # Replace the config only if it has changed to avoid triggering unnecessary rebuilds
        COMMAND                 bash -c "(! diff -q args.gn.tmp args.gn && mv args.gn.tmp args.gn) || true" 
        # Regenerate the ninja build system
        COMMAND                 ${GN_EXECUTABLE}
                                    --root=${CHIP_ROOT}
                                    --root-target=${GN_ROOT_TARGET}
                                    --dotfile=${GN_ROOT_TARGET}/.gn
                                    --script-executable=${Python3_EXECUTABLE}
                                    gen --check --fail-on-unused-args ${CMAKE_CURRENT_BINARY_DIR}
        COMMAND                 ninja
        COMMAND                 ${CMAKE_COMMAND} -E echo "Matter library build complete"
        INSTALL_COMMAND         ""
        # Byproducts are removed by the clean target removing config and .ninja_deps
        # allows a rebuild of the external project after the clean target has been run. 
        BUILD_BYPRODUCTS        ${CMAKE_CURRENT_BINARY_DIR}/args.gn
                                ${CMAKE_CURRENT_BINARY_DIR}/build.ninja
                                ${CMAKE_CURRENT_BINARY_DIR}/.ninja_deps
                                ${CMAKE_CURRENT_BINARY_DIR}/build.ninja.stamp
                                ${MATTER_LIBRARIES}
        BUILD_ALWAYS            TRUE
        USES_TERMINAL_CONFIGURE TRUE
        USES_TERMINAL_BUILD     TRUE
    )

    if(ARG_GN_DEPENDENCIES)
        add_dependencies(chip-gn ${ARG_GN_DEPENDENCIES})
    endif()

    # ==============================================================================
    # Define target that exposes Matter headers & libraries to the application
    # ==============================================================================
    add_library(${target} INTERFACE)
    target_compile_definitions(${target} INTERFACE CHIP_HAVE_CONFIG_H)
    target_include_directories(${target} INTERFACE
        ${CHIP_ROOT}/src
        ${CHIP_ROOT}/src/include
        ${CHIP_ROOT}/third_party/nlassert/repo/include
        ${CHIP_ROOT}/third_party/nlio/repo/include
        ${CHIP_ROOT}/zzz_generated/app-common
        ${CMAKE_CURRENT_BINARY_DIR}/gen/include
    )

    # ==============================================================================
    # Link required libraries
    # ==============================================================================
    target_link_libraries(${target} INTERFACE -Wl,--start-group ${MATTER_LIBRARIES} -Wl,--end-group)
    add_dependencies(${target} chip-gn)

    if (ARG_LIB_SHELL)
        target_link_options(${target} INTERFACE -Wl,--whole-archive ${MATTER_LIB_DIR}/libCHIPShell.a -Wl,--no-whole-archive)
    endif()

    if (ARG_LIB_TESTS)
        target_link_options(${target} INTERFACE -Wl,--whole-archive ${MATTER_LIB_DIR}/libCHIP_tests.a -Wl,--no-whole-archive)
    endif()

    if (ARG_DEVICE_INFO_EXAMPLE_PROVIDER)
        target_include_directories(${target} INTERFACE ${CHIP_ROOT}/examples/providers)
    endif()
endmacro()
