# 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:
#   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.
    if(NOT "${CONF_FILE_BUILD_TYPE}" STREQUAL "")
      set(sysbuild_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}_${CONF_FILE_BUILD_TYPE}.conf)
    else()
      set(sysbuild_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}.conf)
    endif()

    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}_CACHE_FILE ${ZCMAKE_APPLICATION} CACHE_FILE)
  get_target_property(${ZCMAKE_APPLICATION}_BOARD      ${ZCMAKE_APPLICATION} BOARD)
  get_target_property(${ZCMAKE_APPLICATION}_MAIN_APP   ${ZCMAKE_APPLICATION} MAIN_APP)

  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()

  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=${ZCMAKE_APPLICATION}\n")

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

  if(${ZCMAKE_APPLICATION}_BOARD AND NOT DEFINED CACHE{${ZCMAKE_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
         "${ZCMAKE_APPLICATION}_BOARD:STRING=${${ZCMAKE_APPLICATION}_BOARD}\n"
    )
  endif()

  file(WRITE ${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp ${sysbuild_cache_strings})
  zephyr_file_copy(${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp
                   ${${ZCMAKE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT
  )

  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>] [EXTRA_ARGS <arguments>])
#
# This function invokes the sysbuild hook provided as <hook> for <modules>.
#
# If `IMAGES` is passed, then the provided list of of images will be passed 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 images
# 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.
#
function(sysbuild_module_call)
  set(options "PRE_CMAKE;POST_CMAKE;PRE_DOMAINS;POST_DOMAINS")
  set(multi_args "MODULES;IMAGES;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})

  foreach(call ${options})
    if(SMC_${call})
      foreach(module ${SMC_MODULES})
        if(COMMAND ${module}_${call})
          cmake_language(CALL ${module}_${call} IMAGES ${SMC_IMAGES} ${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()
