# Copyright (c) 2021-2023 Nordic Semiconductor
#
# SPDX-License-Identifier: Apache-2.0

# Usage:
#   load_cache(IMAGE <image> BINARY_DIR <dir>)
#
# This function will load the CMakeCache.txt file from the binary directory
# given by the BINARY_DIR argument.
#
# All CMake cache variables are stored in a custom target which is identified by
# the name given as value to the IMAGE argument.
#
# IMAGE:      image name identifying the cache for later sysbuild_get() lookup calls.
# BINARY_DIR: binary directory (build dir) containing the CMakeCache.txt file to load.
function(load_cache)
  set(single_args IMAGE BINARY_DIR)
  cmake_parse_arguments(LOAD_CACHE "" "${single_args}" "" ${ARGN})

  if(NOT TARGET ${LOAD_CACHE_IMAGE}_cache)
    add_custom_target(${LOAD_CACHE_IMAGE}_cache)
  endif()
  file(STRINGS "${LOAD_CACHE_BINARY_DIR}/CMakeCache.txt" cache_strings)
  foreach(str ${cache_strings})
    # Using a regex for matching whole 'VAR_NAME:TYPE=VALUE' will strip semi-colons
    # thus resulting in lists to become strings.
    # Therefore we first fetch VAR_NAME and TYPE, and afterwards extract
    # remaining of string into a value that populates the property.
    # This method ensures that both quoted values and ;-separated list stays intact.
    string(REGEX MATCH "([^:]*):([^=]*)=" variable_identifier ${str})
    if(NOT "${variable_identifier}" STREQUAL "")
      string(LENGTH ${variable_identifier} variable_identifier_length)
      string(SUBSTRING "${str}" ${variable_identifier_length} -1 variable_value)
      set_property(TARGET ${LOAD_CACHE_IMAGE}_cache APPEND PROPERTY "CACHE:VARIABLES" "${CMAKE_MATCH_1}")
      set_property(TARGET ${LOAD_CACHE_IMAGE}_cache PROPERTY "${CMAKE_MATCH_1}:TYPE" "${CMAKE_MATCH_2}")
      set_property(TARGET ${LOAD_CACHE_IMAGE}_cache PROPERTY "${CMAKE_MATCH_1}" "${variable_value}")
      if("${CMAKE_MATCH_1}" MATCHES "^BYPRODUCT_.*")
        set_property(TARGET ${LOAD_CACHE_IMAGE}_cache APPEND
                     PROPERTY "EXTRA_BYPRODUCTS" "${variable_value}"
        )
      endif()
    endif()
  endforeach()
endfunction()

# Usage:
#   sysbuild_get(<variable> IMAGE <image> [VAR <image-variable>] <KCONFIG|CACHE>)
#
# This function will return the variable found in the CMakeCache.txt file
# identified by image.
# If `VAR` is provided, the name given as parameter will be looked up, but if
# `VAR` is not given, the `<variable>` name provided will be used both for
# lookup and value return.
#
# The result will be returned in `<variable>`.
#
# Example use:
#   sysbuild_get(PROJECT_NAME IMAGE my_sample CACHE)
#     will lookup PROJECT_NAME from the CMakeCache identified by `my_sample` and
#     and return the value in the local variable `PROJECT_NAME`.
#
#   sysbuild_get(my_sample_PROJECT_NAME IMAGE my_sample VAR PROJECT_NAME CACHE)
#     will lookup PROJECT_NAME from the CMakeCache identified by `my_sample` and
#     and return the value in the local variable `my_sample_PROJECT_NAME`.
#
#   sysbuild_get(my_sample_CONFIG_FOO IMAGE my_sample VAR CONFIG_FOO KCONFIG)
#     will lookup CONFIG_FOO from the KConfig identified by `my_sample` and
#     and return the value in the local variable `my_sample_CONFIG_FOO`.
#
# <variable>: variable used for returning CMake cache value. Also used as lookup
#             variable if `VAR` is not provided.
# IMAGE:      image name identifying the cache to use for variable lookup.
# VAR:        name of the CMake cache variable name to lookup.
# KCONFIG:    Flag indicating that a Kconfig setting should be fetched.
# CACHE:      Flag indicating that a CMake cache variable should be fetched.
function(sysbuild_get variable)
  cmake_parse_arguments(GET_VAR "CACHE;KCONFIG" "IMAGE;VAR" "" ${ARGN})

  if(NOT DEFINED GET_VAR_IMAGE)
    message(FATAL_ERROR "sysbuild_get(...) requires IMAGE.")
  endif()

  if(DEFINED ${variable} AND NOT DEFINED GET_VAR_VAR)
    message(WARNING "Return variable ${variable} already defined with a value. "
                    "sysbuild_get(${variable} ...) may overwrite existing value. "
		    "Please use sysbuild_get(<variable> ... VAR <image-variable>) "
		    "where <variable> is undefined."
    )
  endif()

  if(NOT DEFINED GET_VAR_VAR)
    set(GET_VAR_VAR ${variable})
  endif()

  if(GET_VAR_KCONFIG)
    set(variable_target ${GET_VAR_IMAGE})
  elseif(GET_VAR_CACHE)
    set(variable_target ${GET_VAR_IMAGE}_cache)
  else()
    message(WARNING "<CACHE> or <KCONFIG> not specified, defaulting to CACHE")
    set(variable_target ${GET_VAR_IMAGE}_cache)
  endif()

  get_property(${GET_VAR_IMAGE}_${GET_VAR_VAR} TARGET ${variable_target} PROPERTY ${GET_VAR_VAR})
  if(DEFINED ${GET_VAR_IMAGE}_${GET_VAR_VAR})
    set(${variable} ${${GET_VAR_IMAGE}_${GET_VAR_VAR}} PARENT_SCOPE)
  endif()
endfunction()

# Usage:
#   sysbuild_cache(CREATE APPLICATION <name> [CMAKE_RERUN])
#
# This function works on the sysbuild cache for sysbuild managed applications.
#
# Arguments:
# CREATE            : Create or update existing sysbuild cache file for the application.
#                     The sysbuild cache is only updated if it contain changes.
# APPLICATION <name>: Name of the application.
# CMAKE_RERUN       : Force a CMake rerun for the application during next build
#                     invocation if the sysbuild cache has changed. It is
#                     advised to always use this flag. Not using this flag can
#                     reduce build time, but only do so if application is
#                     guranteed to be up-to-date.
#
function(sysbuild_cache)
  cmake_parse_arguments(SB_CACHE "CREATE;CMAKE_RERUN" "APPLICATION" "" ${ARGN})
  zephyr_check_arguments_required(sysbuild_cache SB_CACHE APPLICATION)
  zephyr_check_flags_required(sysbuild_cache SB_CACHE CREATE)

  get_target_property(${SB_CACHE_APPLICATION}_MAIN_APP ${SB_CACHE_APPLICATION} MAIN_APP)
  get_cmake_property(sysbuild_cache CACHE_VARIABLES)

  foreach(var_name ${sysbuild_cache})
    if(NOT "${var_name}" MATCHES "^(CMAKE_.*|BOARD)$")
      # Perform a dummy read to prevent a false warning about unused variables
      # being emitted due to a cmake bug: https://gitlab.kitware.com/cmake/cmake/-/issues/24555
      set(unused_tmp_var ${${var_name}})

      # We don't want to pass internal CMake variables.
      # Required CMake variable to be passed, like CMAKE_BUILD_TYPE must be
      # passed using `-D` on command invocation.
      get_property(var_type CACHE ${var_name} PROPERTY TYPE)
      set(cache_entry "${var_name}:${var_type}=$CACHE{${var_name}}")
      string(REPLACE ";" "\;" cache_entry "${cache_entry}")
      list(APPEND sysbuild_cache_strings "${cache_entry}\n")
    endif()
  endforeach()
  if(DEFINED BOARD_REVISION)
    list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}@${BOARD_REVISION}\n")
  else()
    list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}\n")
  endif()
  list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${SB_CACHE_APPLICATION}\n")

  if(${SB_CACHE_APPLICATION}_MAIN_APP)
    list(APPEND sysbuild_cache_strings "SYSBUILD_MAIN_APP:BOOL=True\n")
  endif()

  if(${SB_CACHE_APPLICATION}_BOARD AND NOT DEFINED CACHE{${SB_CACHE_APPLICATION}_BOARD})
    # Only set image specific board if provided.
    # The sysbuild BOARD is exported through sysbuild cache, and will be used
    # unless <image>_BOARD is defined.
    list(APPEND sysbuild_cache_strings
         "${SB_CACHE_APPLICATION}_BOARD:STRING=${${SB_CACHE_APPLICATION}_BOARD}\n"
    )
  endif()

  get_target_property(${SB_CACHE_APPLICATION}_CACHE_FILE ${SB_CACHE_APPLICATION} CACHE_FILE)
  file(WRITE ${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp ${sysbuild_cache_strings})
  if(SB_CACHE_CMAKE_RERUN)
    execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files
                    ${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp
                    ${${SB_CACHE_APPLICATION}_CACHE_FILE}
                    RESULT_VARIABLE compare_res
    )
    if(NOT compare_res EQUAL 0)
      zephyr_file_copy(${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp
                       ${${SB_CACHE_APPLICATION}_CACHE_FILE}
      )
      ExternalProject_Get_Property(${SB_CACHE_APPLICATION} BINARY_DIR)
      file(TOUCH_NOCREATE ${BINARY_DIR}/CMakeCache.txt)
    endif()
  else()
    zephyr_file_copy(${${SB_CACHE_APPLICATION}_CACHE_FILE}.tmp
                     ${${SB_CACHE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT
    )
  endif()

endfunction()

# Usage:
#   ExternalZephyrProject_Add(APPLICATION <name>
#                             SOURCE_DIR <dir>
#                             [BOARD <board> [BOARD_REVISION <revision>]]
#                             [APP_TYPE <MAIN|BOOTLOADER>]
#   )
#
# This function includes a Zephyr based build system into the multiimage
# build system
#
# APPLICATION: <name>:       Name of the application, name will also be used for build
#                            folder of the application
# SOURCE_DIR <dir>:          Source directory of the application
# BOARD <board>:             Use <board> for application build instead user defined BOARD.
# BOARD_REVISION <revision>: Use <revision> of <board> for application (only valid if
#                            <board> is also supplied).
# APP_TYPE <MAIN|BOOTLOADER>: Application type.
#                             MAIN indicates this application is the main application
#                             and where user defined settings should be passed on as-is
#                             except for multi image build flags.
#                             For example, -DCONF_FILES=<files> will be passed on to the
#                             MAIN_APP unmodified.
#                             BOOTLOADER indicates this app is a bootloader
# BUILD_ONLY <bool>:          Mark the application as build-only. If <bool> evaluates to
#                             true, then this application will be excluded from flashing
#                             and debugging.
#
function(ExternalZephyrProject_Add)
  set(app_types MAIN BOOTLOADER)
  cmake_parse_arguments(ZBUILD "" "APPLICATION;BOARD;BOARD_REVISION;SOURCE_DIR;APP_TYPE;BUILD_ONLY" "" ${ARGN})

  if(ZBUILD_UNPARSED_ARGUMENTS)
    message(FATAL_ERROR
      "ExternalZephyrProject_Add(${ARGV0} <val> ...) given unknown arguments:"
      " ${ZBUILD_UNPARSED_ARGUMENTS}"
    )
  endif()

  if(TARGET ${ZBUILD_APPLICATION})
    message(FATAL_ERROR
      "ExternalZephyrProject_Add(APPLICATION ${ZBUILD_APPLICATION} ...) "
      "already exists. Application names must be unique."
    )
  endif()

  if(DEFINED ZBUILD_APP_TYPE)
    if(NOT ZBUILD_APP_TYPE IN_LIST app_types)
      message(FATAL_ERROR
        "ExternalZephyrProject_Add(APP_TYPE <val> ...) given unknown type: ${ZBUILD_APP_TYPE}\n"
        "Valid types are: ${app_types}"
      )
    endif()

  endif()

  if(NOT DEFINED SYSBUILD_CURRENT_SOURCE_DIR)
    message(FATAL_ERROR
      "ExternalZephyrProject_Add(${ARGV0} <val> ...) must not be called outside of"
      " sysbuild_add_subdirectory(). SYSBUILD_CURRENT_SOURCE_DIR is undefined."
    )
  endif()
  set_property(
    DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}"
    APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION}
  )
  set_property(
    GLOBAL
    APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION}
  )

  set(sysbuild_image_conf_dir ${APP_DIR}/sysbuild)
  set(sysbuild_image_name_conf_dir ${APP_DIR}/sysbuild/${ZBUILD_APPLICATION})
  # User defined `-D<image>_CONF_FILE=<file.conf>` takes precedence over anything else.
  if (NOT ${ZBUILD_APPLICATION}_CONF_FILE)
    if(EXISTS ${sysbuild_image_name_conf_dir})
      set(${ZBUILD_APPLICATION}_APPLICATION_CONFIG_DIR ${sysbuild_image_name_conf_dir}
          CACHE INTERNAL "Application configuration dir controlled by sysbuild"
      )
    endif()

    # Check for sysbuild related configuration fragments.
    # The contents of these are appended to the image existing configuration
    # when user is not specifying custom fragments.
    zephyr_file(CONF_FILES ${sysbuild_image_conf_dir} KCONF sysbuild_image_conf_fragment
                NAMES ${ZBUILD_APPLICATION}.conf SUFFIX ${FILE_SUFFIX}
    )

    if (NOT (${ZBUILD_APPLICATION}_OVERLAY_CONFIG OR ${ZBUILD_APPLICATION}_EXTRA_CONF_FILE)
        AND EXISTS ${sysbuild_image_conf_fragment}
    )
      set(${ZBUILD_APPLICATION}_EXTRA_CONF_FILE ${sysbuild_image_conf_fragment}
          CACHE INTERNAL "Kconfig fragment defined by main application"
      )
    endif()

    # Check for overlay named <ZBUILD_APPLICATION>.overlay.
    set(sysbuild_image_dts_overlay ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}.overlay)
    if (NOT ${ZBUILD_APPLICATION}_DTC_OVERLAY_FILE AND EXISTS ${sysbuild_image_dts_overlay})
      set(${ZBUILD_APPLICATION}_DTC_OVERLAY_FILE ${sysbuild_image_dts_overlay}
          CACHE INTERNAL "devicetree overlay file defined by main application"
      )
    endif()
  endif()

  # Update ROOT variables with relative paths to use absolute paths based on
  # the source application directory.
  foreach(type MODULE_EXT BOARD SOC ARCH SCA)
    if(DEFINED CACHE{${ZBUILD_APPLICATION}_${type}_ROOT} AND NOT IS_ABSOLUTE $CACHE{${ZBUILD_APPLICATION}_${type}_ROOT})
      set(rel_path $CACHE{${ZBUILD_APPLICATION}_${type}_ROOT})
      cmake_path(ABSOLUTE_PATH rel_path BASE_DIRECTORY "${ZBUILD_SOURCE_DIR}" NORMALIZE OUTPUT_VARIABLE abs_path)
      set(${ZBUILD_APPLICATION}_${type}_ROOT ${abs_path} CACHE PATH "Sysbuild adjusted absolute path" FORCE)
    endif()
  endforeach()

  # CMake variables which must be known by all Zephyr CMake build systems
  # Those are settings which controls the build and must be known to CMake at
  # invocation time, and thus cannot be passed though the sysbuild cache file.
  set(
    shared_cmake_variables_list
    CMAKE_BUILD_TYPE
    CMAKE_VERBOSE_MAKEFILE
  )

  set(sysbuild_cache_file ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}_sysbuild_cache.txt)

  set(shared_cmake_vars_argument)
  foreach(shared_var ${shared_cmake_variables_list})
    if(DEFINED CACHE{${ZBUILD_APPLICATION}_${shared_var}})
      get_property(var_type  CACHE ${ZBUILD_APPLICATION}_${shared_var} PROPERTY TYPE)
      list(APPEND shared_cmake_vars_argument
           "-D${shared_var}:${var_type}=$CACHE{${ZBUILD_APPLICATION}_${shared_var}}"
      )
    elseif(DEFINED CACHE{${shared_var}})
      get_property(var_type  CACHE ${shared_var} PROPERTY TYPE)
      list(APPEND shared_cmake_vars_argument
           "-D${shared_var}:${var_type}=$CACHE{${shared_var}}"
      )
    endif()
  endforeach()

  foreach(kconfig_target
      menuconfig
      hardenconfig
      guiconfig
      ${EXTRA_KCONFIG_TARGETS}
      )

    if(NOT ZBUILD_APP_TYPE STREQUAL "MAIN")
      set(image_prefix "${ZBUILD_APPLICATION}_")
    endif()

    add_custom_target(${image_prefix}${kconfig_target}
      ${CMAKE_MAKE_PROGRAM} ${kconfig_target}
      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}
      USES_TERMINAL
      )
  endforeach()
  include(ExternalProject)
  set(application_binary_dir ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION})
  ExternalProject_Add(
    ${ZBUILD_APPLICATION}
    SOURCE_DIR ${ZBUILD_SOURCE_DIR}
    BINARY_DIR ${application_binary_dir}
    CONFIGURE_COMMAND ""
    CMAKE_ARGS -DSYSBUILD:BOOL=True
               -DSYSBUILD_CACHE:FILEPATH=${sysbuild_cache_file}
               ${shared_cmake_vars_argument}
    BUILD_COMMAND ${CMAKE_COMMAND} --build .
    INSTALL_COMMAND ""
    BUILD_ALWAYS True
    USES_TERMINAL_BUILD True
  )
  set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY APP_TYPE ${ZBUILD_APP_TYPE})
  set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY CONFIG
               "# sysbuild controlled configuration settings\n"
  )
  set_target_properties(${ZBUILD_APPLICATION} PROPERTIES CACHE_FILE ${sysbuild_cache_file})
  set_target_properties(${ZBUILD_APPLICATION} PROPERTIES KCONFIG_BINARY_DIR
                        ${application_binary_dir}/Kconfig
  )
  if("${ZBUILD_APP_TYPE}" STREQUAL "MAIN")
    set_target_properties(${ZBUILD_APPLICATION} PROPERTIES MAIN_APP True)
  endif()

  if(DEFINED ZBUILD_APP_TYPE)
    set(image_default "${CMAKE_SOURCE_DIR}/image_configurations/${ZBUILD_APP_TYPE}_image_default.cmake")
    set_target_properties(${ZBUILD_APPLICATION} PROPERTIES IMAGE_CONF_SCRIPT ${image_default})
  endif()

  if(DEFINED ZBUILD_BOARD)
    # Only set image specific board if provided.
    # The sysbuild BOARD is exported through sysbuild cache, and will be used
    # unless <image>_BOARD is defined.
    if(DEFINED ZBUILD_BOARD_REVISION)
      # Use provided board revision
      set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${ZBUILD_BOARD}@${ZBUILD_BOARD_REVISION})
    else()
      set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${ZBUILD_BOARD})
    endif()
  elseif(DEFINED ZBUILD_BOARD_REVISION)
    message(FATAL_ERROR
      "ExternalZephyrProject_Add(... BOARD_REVISION ${ZBUILD_BOARD_REVISION})"
      " requires BOARD."
    )
  endif()

  if(DEFINED ZBUILD_BUILD_ONLY)
    set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BUILD_ONLY ${ZBUILD_BUILD_ONLY})
  endif()
endfunction()

# Usage:
#   ExternalZephyrProject_Cmake(APPLICATION <name>)
#
# This function invokes the CMake configure step on an external Zephyr project
# which has been added at an earlier stage using `ExternalZephyrProject_Add()`
#
# If the application is not due to ExternalZephyrProject_Add() being called,
# then an error is raised.
#
# The image output files are added as target properties on the image target as:
# ELF_OUT: property specifying the generated elf file.
# BIN_OUT: property specifying the generated bin file.
# HEX_OUT: property specifying the generated hex file.
# S19_OUT: property specifying the generated s19 file.
# UF2_OUT: property specifying the generated uf2 file.
# EXE_OUT: property specifying the generated exe file.
#
# the property is only set if the image is configured to generate the output
# format. Elf files are always created.
#
# APPLICATION: <name>: Name of the application.
#
function(ExternalZephyrProject_Cmake)
  cmake_parse_arguments(ZCMAKE "" "APPLICATION" "" ${ARGN})

  if(ZBUILD_UNPARSED_ARGUMENTS)
    message(FATAL_ERROR
      "ExternalZephyrProject_Cmake(${ARGV0} <val> ...) given unknown arguments:"
      " ${ZBUILD_UNPARSED_ARGUMENTS}"
    )
  endif()

  if(NOT DEFINED ZCMAKE_APPLICATION)
    message(FATAL_ERROR "Missing required argument: APPLICATION")
  endif()

  if(NOT TARGET ${ZCMAKE_APPLICATION})
    message(FATAL_ERROR
      "${ZCMAKE_APPLICATION} does not exists. Remember to call "
      "ExternalZephyrProject_Add(APPLICATION ${ZCMAKE_APPLICATION} ...) first."
    )
  endif()

  set(image_banner "* Running CMake for ${ZCMAKE_APPLICATION} *")
  string(LENGTH "${image_banner}" image_banner_width)
  string(REPEAT "*" ${image_banner_width} image_banner_header)
  message(STATUS "\n   ${image_banner_header}\n"
                 "   ${image_banner}\n"
                 "   ${image_banner_header}\n"
  )

  ExternalProject_Get_Property(${ZCMAKE_APPLICATION} SOURCE_DIR BINARY_DIR CMAKE_ARGS)
  get_target_property(${ZCMAKE_APPLICATION}_BOARD      ${ZCMAKE_APPLICATION} BOARD)

  get_property(${ZCMAKE_APPLICATION}_CONF_SCRIPT TARGET ${ZCMAKE_APPLICATION}
               PROPERTY IMAGE_CONF_SCRIPT
  )

  # Update ROOT variables with relative paths to use absolute paths based on
  # the source application directory.
  foreach(type MODULE_EXT BOARD SOC ARCH SCA)
    if(DEFINED CACHE{${type}_ROOT} AND NOT IS_ABSOLUTE $CACHE{${type}_ROOT})
      set(rel_path $CACHE{${type}_ROOT})
      cmake_path(ABSOLUTE_PATH rel_path BASE_DIRECTORY "${APP_DIR}" NORMALIZE OUTPUT_VARIABLE abs_path)
      set(${type}_ROOT ${abs_path} CACHE PATH "Sysbuild adjusted absolute path" FORCE)
    endif()
  endforeach()

  sysbuild_cache(CREATE APPLICATION ${ZCMAKE_APPLICATION})

  foreach(script ${${ZCMAKE_APPLICATION}_CONF_SCRIPT})
    include(${script})
  endforeach()

  set(dotconfigsysbuild ${BINARY_DIR}/zephyr/.config.sysbuild)
  get_target_property(config_content ${ZCMAKE_APPLICATION} CONFIG)
  string(CONFIGURE "${config_content}" config_content)
  file(WRITE ${dotconfigsysbuild} ${config_content})

  execute_process(
    COMMAND ${CMAKE_COMMAND}
      -G${CMAKE_GENERATOR}
        ${CMAKE_ARGS}
      -DFORCED_CONF_FILE:FILEPATH=${dotconfigsysbuild}
      -B${BINARY_DIR}
      -S${SOURCE_DIR}
    RESULT_VARIABLE   return_val
    WORKING_DIRECTORY ${BINARY_DIR}
  )

  if(return_val)
    message(FATAL_ERROR
            "CMake configure failed for Zephyr project: ${ZCMAKE_APPLICATION}\n"
            "Location: ${SOURCE_DIR}"
    )
  endif()
  load_cache(IMAGE ${ZCMAKE_APPLICATION} BINARY_DIR ${BINARY_DIR})
  import_kconfig(CONFIG_ ${BINARY_DIR}/zephyr/.config TARGET ${ZCMAKE_APPLICATION})

  # This custom target informs CMake how the BYPRODUCTS are generated if a target
  # depends directly on the BYPRODUCT instead of depending on the image target.
  get_target_property(${ZCMAKE_APPLICATION}_byproducts ${ZCMAKE_APPLICATION}_cache EXTRA_BYPRODUCTS)
  add_custom_target(${ZCMAKE_APPLICATION}_extra_byproducts
                    COMMAND ${CMAKE_COMMAND} -E true
                    BYPRODUCTS ${${ZCMAKE_APPLICATION}_byproducts}
                    DEPENDS ${ZCMAKE_APPLICATION}
  )
endfunction()

# Usage:
#   sysbuild_module_call(<hook> MODULES <modules> IMAGES <images> [IMAGE <image>] [EXTRA_ARGS <arguments>])
#
# This function invokes the sysbuild hook provided as <hook> for <modules>.
#
# `IMAGES` contains the list of images to the hook, if `IMAGE` is passed, this will be provided
# to the hook.
#
# `EXTRA_ARGS` can be used to pass extra arguments to the hook.
#
# Valid <hook> values:
# PRE_CMAKE       : Invoke pre-CMake call for modules before CMake configure is invoked for images
# POST_CMAKE      : Invoke post-CMake call for modules after CMake configure has been invoked for
# PRE_IMAGE_CMAKE : Invoke pre-CMake call for modules before CMake configure is invoked for each
#                   image
# POST_IMAGE_CMAKE: Invoke post-CMake call for modules after CMake configure has been invoked for
#                   each image
# PRE_DOMAINS     : Invoke pre-domains call for modules before creating domains yaml
# POST_DOMAINS    : Invoke post-domains call for modules after creation of domains yaml
#
# For the `PRE_IMAGE_CMAKE` and `POST_IMAGE_CMAKE` hooks, `IMAGE` is provided
#
function(sysbuild_module_call)
  set(options "PRE_CMAKE;POST_CMAKE;PRE_IMAGE_CMAKE;POST_IMAGE_CMAKE;PRE_DOMAINS;POST_DOMAINS")
  set(multi_args "MODULES;IMAGES;IMAGE;EXTRA_ARGS")
  cmake_parse_arguments(SMC "${options}" "${test_args}" "${multi_args}" ${ARGN})

  zephyr_check_flags_required("sysbuild_module_call" SMC ${options})
  zephyr_check_flags_exclusive("sysbuild_module_call" SMC ${options})

  if(NOT DEFINED SMC_IMAGES)
    message(FATAL_ERROR
            "sysbuild_module_call(...) missing required IMAGES option")
  endif()

  if(DEFINED SMC_IMAGE)
    set(IMAGE_ARG IMAGE ${SMC_IMAGE})
  elseif(SMC_PRE_IMAGE_CMAKE)
    message(FATAL_ERROR
            "sysbuild_module_call(PRE_IMAGE_CMAKE ...) missing required IMAGE option")
  elseif(SMC_POST_IMAGE_CMAKE)
    message(FATAL_ERROR
            "sysbuild_module_call(POST_IMAGE_CMAKE ...) missing required IMAGE option")
  endif()

  foreach(call ${options})
    if(SMC_${call})
      foreach(module ${SMC_MODULES})
        if(COMMAND ${module}_${call})
          cmake_language(CALL ${module}_${call} IMAGES ${SMC_IMAGES} ${IMAGE_ARG} ${SMC_EXTRA_ARGS})
        endif()
      endforeach()
    endif()
  endforeach()
endfunction()

# Usage:
#   sysbuild_cache_set(VAR <variable> [APPEND [REMOVE_DUPLICATES]] <value>)
#
# This function will set the specified value of the sysbuild cache variable in
# the CMakeCache.txt file which can then be accessed by images.
# `VAR` specifies the variable name to set/update.
#
# The result will be returned in `<variable>`.
#
# Example use:
#   sysbuild_cache_set(VAR ATTRIBUTES APPEND REMOVE_DUPLICATES battery)
#     Will add the item `battery` to the `ATTRIBUTES` variable as a new element
#     in the list in the CMakeCache and remove any duplicates from the list.
#
# <variable>:        Name of variable in CMake cache.
# APPEND:            If specified then will append the supplied data to the
#                    existing value as a list.
# REMOVE_DUPLICATES: If specified then remove duplicate entries contained
#                    within the list before saving to the cache.
# <value>:           Value to set/update.
function(sysbuild_cache_set)
  cmake_parse_arguments(VARS "APPEND;REMOVE_DUPLICATES" "VAR" "" ${ARGN})

  zephyr_check_arguments_required(sysbuild_cache_set VARS VAR)

  if(NOT VARS_UNPARSED_ARGUMENTS AND VARS_APPEND)
    # Nothing to append so do nothing
    return()
  elseif(VARS_REMOVE_DUPLICATES AND NOT VARS_APPEND)
    message(FATAL_ERROR
            "sysbuild_set(VAR <var> APPEND REMOVE_DUPLICATES ...) missing required APPEND option")
  endif()

  get_property(var_type CACHE ${VARS_VAR} PROPERTY TYPE)
  get_property(var_help CACHE ${VARS_VAR} PROPERTY HELPSTRING)

  # If the variable type is not set, use UNINITIALIZED which will not apply any
  # specific formatting.
  if(NOT var_type)
    set(var_type "UNINITIALIZED")
  endif()

  if(VARS_APPEND)
    set(var_new "$CACHE{${VARS_VAR}}")

    # Search for these exact items in the existing value and prevent adding
    # them if they are already present which avoids issues with double addition
    # when cmake is reran.
    string(FIND "$CACHE{${VARS_VAR}}" "${VARS_UNPARSED_ARGUMENTS}" index)

    if(NOT ${index} EQUAL -1)
      return()
    endif()

    list(APPEND var_new "${VARS_UNPARSED_ARGUMENTS}")

    if(VARS_REMOVE_DUPLICATES)
      list(REMOVE_DUPLICATES var_new)
    endif()
  else()
    set(var_new "${VARS_UNPARSED_ARGUMENTS}")
  endif()

  set(${VARS_VAR} "${var_new}" CACHE "${var_type}" "${var_help}" FORCE)
endfunction()

function(set_config_bool image setting value)
  if(${value})
    set_property(TARGET ${image} APPEND_STRING PROPERTY CONFIG "${setting}=y\n")
  else()
    set_property(TARGET ${image} APPEND_STRING PROPERTY CONFIG "${setting}=n\n")
  endif()
endfunction()

function(set_config_string image setting value)
  set_property(TARGET ${image} APPEND_STRING PROPERTY CONFIG "${setting}=\"${value}\"\n")
endfunction()

# Usage:
#   sysbuild_add_subdirectory(<source_dir> [<binary_dir>])
#
# This function extends the standard add_subdirectory() command with additional,
# recursive processing of the sysbuild images added via <source_dir>.
#
# After exiting <source_dir>, this function will take every image added so far,
# and include() its sysbuild.cmake file (if found). If more images get added at
# this stage, their sysbuild.cmake files will be included as well, and so on.
# This continues until all expected images have been added, before returning.
#
function(sysbuild_add_subdirectory source_dir)
  if(ARGC GREATER 2)
    message(FATAL_ERROR
      "sysbuild_add_subdirectory(...) called with incorrect number of arguments"
      " (expected at most 2, got ${ARGC})"
    )
  endif()
  set(binary_dir ${ARGV1})

  # Update SYSBUILD_CURRENT_SOURCE_DIR in this scope, to support nesting
  # of sysbuild_add_subdirectory() and even regular add_subdirectory().
  cmake_path(ABSOLUTE_PATH source_dir NORMALIZE OUTPUT_VARIABLE SYSBUILD_CURRENT_SOURCE_DIR)
  add_subdirectory(${source_dir} ${binary_dir})

  while(TRUE)
    get_property(added_images DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}" PROPERTY sysbuild_images)
    if(NOT added_images)
      break()
    endif()
    set_property(DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}" PROPERTY sysbuild_images "")

    foreach(image ${added_images})
      ExternalProject_Get_property(${image} SOURCE_DIR)
      include(${SOURCE_DIR}/sysbuild.cmake OPTIONAL)
    endforeach()
  endwhile()
endfunction()

# Usage:
#   sysbuild_add_dependencies(<CONFIGURE | FLASH> <image> [<image-dependency> ...])
#
# This function makes an image depend on other images in the configuration or
# flashing order. Each image named "<image-dependency>" will be ordered before
# the image named "<image>".
#
# CONFIGURE: Add CMake configuration dependencies. This will determine the order
#            in which `ExternalZephyrProject_Cmake()` will be called.
# FLASH:     Add flashing dependencies. This will determine the order in which
#            all images will appear in `domains.yaml`.
#
function(sysbuild_add_dependencies dependency_type image)
  set(valid_dependency_types CONFIGURE FLASH)
  if(NOT dependency_type IN_LIST valid_dependency_types)
    list(JOIN valid_dependency_types ", " valid_dependency_types)
    message(FATAL_ERROR "sysbuild_add_dependencies(...) dependency type "
                        "${dependency_type} must be one of the following: "
                        "${valid_dependency_types}"
    )
  endif()

  if(NOT TARGET ${image})
    message(FATAL_ERROR
      "${image} does not exist. Remember to call "
      "ExternalZephyrProject_Add(APPLICATION ${image} ...) first."
    )
  endif()

  get_target_property(image_is_build_only ${image} BUILD_ONLY)
  if(image_is_build_only AND dependency_type STREQUAL "FLASH")
    message(FATAL_ERROR
      "sysbuild_add_dependencies(...) cannot add FLASH dependencies to "
      "BUILD_ONLY image ${image}."
    )
  endif()

  set(property_name ${dependency_type}_DEPENDS)
  set_property(TARGET ${image} APPEND PROPERTY ${property_name} ${ARGN})
endfunction()

# Usage:
#   sysbuild_images_order(<variable> <CONFIGURE | FLASH> IMAGES <images>)
#
# This function will sort the provided `<images>` to satisfy the dependencies
# specified using `sysbuild_add_dependencies()`. The result will be returned in
# `<variable>`.
#
function(sysbuild_images_order variable dependency_type)
  cmake_parse_arguments(SIS "" "" "IMAGES" ${ARGN})
  zephyr_check_arguments_required_all("sysbuild_images_order" SIS IMAGES)

  set(valid_dependency_types CONFIGURE FLASH)
  if(NOT dependency_type IN_LIST valid_dependency_types)
    list(JOIN valid_dependency_types ", " valid_dependency_types)
    message(FATAL_ERROR "sysbuild_images_order(...) dependency type "
                        "${dependency_type} must be one of the following: "
                        "${valid_dependency_types}"
    )
  endif()

  set(property_name ${dependency_type}_DEPENDS)
  topological_sort(TARGETS ${SIS_IMAGES} PROPERTY_NAME ${property_name} RESULT sorted)
  set(${variable} ${sorted} PARENT_SCOPE)
endfunction()
