# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2024, Nordic Semiconductor ASA

# CMake YAML module for handling of YAML files.
#
# This module offers basic support for simple yaml files.
#
# It supports basic key-value pairs, like
# foo: bar
#
# basic key-object pairs, like
# foo:
#    bar: baz
#
# Simple value lists, like:
# foos:
#  - foo1
#  - foo2
#  - foo3
#
# All of above can be combined, for example like:
# foo:
#   bar: baz
#   quz:
#     greek:
#      - alpha
#      - beta
#      - gamma
# fred: thud
#
# Support for list of objects are currently experimental and not guranteed to work.
# For example:
# foo:
#  - bar: val1
#    baz: val1
#  - bar: val2
#    baz: val2

include_guard(GLOBAL)

include(extensions)
include(python)

# Internal helper function for checking that a YAML context has been created
# before operating on it.
# Will result in CMake error if context does not exist.
function(internal_yaml_context_required)
  cmake_parse_arguments(ARG_YAML "" "NAME" "" ${ARGN})
  zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME)
  yaml_context(EXISTS NAME ${ARG_YAML_NAME} result)

  if(NOT result)
    message(FATAL_ERROR "YAML context '${ARG_YAML_NAME}' does not exist."
            "Remember to create a YAML context using 'yaml_create()' or 'yaml_load()'"
    )
  endif()
endfunction()

# Internal helper function for checking if a YAML context is free before creating
# it later.
# Will result in CMake error if context exists.
function(internal_yaml_context_free)
  cmake_parse_arguments(ARG_YAML "" "NAME" "" ${ARGN})
  zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME)
  yaml_context(EXISTS NAME ${ARG_YAML_NAME} result)

  if(result)
    message(FATAL_ERROR "YAML context '${ARG_YAML_NAME}' already exists."
            "Please create a YAML context with a unique name"
    )
  endif()
endfunction()

# Usage
#   yaml_context(EXISTS NAME <name> <result>)
#
# Function to query the status of the YAML context with the name <name>.
# The result of the query is stored in <result>
#
# EXISTS     : Check if the YAML context exists in the current scope
#              If the context exists, then TRUE is returned in <result>
# NAME <name>: Name of the YAML context
# <result>   : Variable to store the result of the query.
#
function(yaml_context)
  cmake_parse_arguments(ARG_YAML "EXISTS" "NAME" "" ${ARGN})
  zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML EXISTS NAME)

  if(NOT DEFINED ARG_YAML_UNPARSED_ARGUMENTS)
    message(FATAL_ERROR "Missing argument in "
            "${CMAKE_CURRENT_FUNCTION}(EXISTS NAME ${ARG_YAML_NAME} <result-var>)."
    )
  endif()

  if(TARGET ${ARG_YAML_NAME}_scope)
    list(POP_FRONT ARG_YAML_UNPARSED_ARGUMENTS out-var)
    set(${out-var} TRUE PARENT_SCOPE)
  else()
    set(${out-var} ${ARG_YAML_NAME}-NOTFOUND PARENT_SCOPE)
  endif()
endfunction()

# Usage:
#   yaml_create(NAME <name> [FILE <file>])
#
# Create a new empty YAML context.
# Use the file <file> for storing the context when 'yaml_save(NAME <name>)' is
# called.
#
# Values can be set by calling 'yaml_set(NAME <name>)' by using the <name>
# specified when creating the YAML context.
#
# NAME <name>: Name of the YAML context.
# FILE <file>: Path to file to be used together with this YAML context.
#
function(yaml_create)
  cmake_parse_arguments(ARG_YAML "" "FILE;NAME" "" ${ARGN})

  zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME)

  internal_yaml_context_free(NAME ${ARG_YAML_NAME})
  zephyr_create_scope(${ARG_YAML_NAME})
  if(DEFINED ARG_YAML_FILE)
    zephyr_set(FILE ${ARG_YAML_FILE} SCOPE ${ARG_YAML_NAME})
  endif()
  zephyr_set(JSON "{}" SCOPE ${ARG_YAML_NAME})
endfunction()

# Usage:
#   yaml_load(FILE <file> NAME <name>)
#
# Load an existing YAML file and store its content in the YAML context <name>.
#
# Values can later be retrieved ('yaml_get()') or set/updated ('yaml_set()') by using
# the same YAML scope name.
#
# FILE <file>: Path to file to load.
# NAME <name>: Name of the YAML context.
#
function(yaml_load)
  cmake_parse_arguments(ARG_YAML "" "FILE;NAME" "" ${ARGN})

  zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML FILE NAME)
  internal_yaml_context_free(NAME ${ARG_YAML_NAME})

  zephyr_create_scope(${ARG_YAML_NAME})
  zephyr_set(FILE ${ARG_YAML_FILE} SCOPE ${ARG_YAML_NAME})

  execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
    "import json; import yaml; print(json.dumps(yaml.safe_load(open('${ARG_YAML_FILE}'))))"
    OUTPUT_VARIABLE json_load_out
    ERROR_VARIABLE json_load_error
    RESULT_VARIABLE json_load_result
  )

  if(json_load_result)
    message(FATAL_ERROR "Failed to load content of YAML file: ${ARG_YAML_FILE}\n"
                        "${json_load_error}"
    )
  endif()

  zephyr_set(JSON "${json_load_out}" SCOPE ${ARG_YAML_NAME})
endfunction()

# Usage:
#   yaml_get(<out-var> NAME <name> KEY <key>...)
#
# Get the value of the given key and store the value in <out-var>.
# If key represents a list, then the list is returned.
#
# Behavior is undefined if key points to a complex object.
#
# NAME <name>  : Name of the YAML context.
# KEY <key>... : Name of key.
# <out-var>    : Name of output variable.
#
function(yaml_get out_var)
  # Current limitation:
  # - Anything will be returned, even json object strings.
  cmake_parse_arguments(ARG_YAML "" "NAME" "KEY" ${ARGN})

  zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY)
  internal_yaml_context_required(NAME ${ARG_YAML_NAME})

  get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON)

  # We specify error variable to avoid a fatal error.
  # If key is not found, then type becomes '-NOTFOUND' and value handling is done below.
  string(JSON type ERROR_VARIABLE error TYPE "${json_content}" ${ARG_YAML_KEY})
  if(type STREQUAL ARRAY)
    string(JSON subjson GET "${json_content}" ${ARG_YAML_KEY})
    string(JSON arraylength LENGTH "${subjson}")
    set(array)
    math(EXPR arraystop "${arraylength} - 1")
    if(arraylength GREATER 0)
      foreach(i RANGE 0 ${arraystop})
        string(JSON item GET "${subjson}" ${i})
        list(APPEND array ${item})
      endforeach()
    endif()
    set(${out_var} ${array} PARENT_SCOPE)
  else()
    # We specify error variable to avoid a fatal error.
    # Searching for a non-existing key should just result in the output value '-NOTFOUND'
    string(JSON value ERROR_VARIABLE error GET "${json_content}" ${ARG_YAML_KEY})
    set(${out_var} ${value} PARENT_SCOPE)
  endif()
endfunction()

# Usage:
#   yaml_length(<out-var> NAME <name> KEY <key>...)
#
# Get the length of the array defined by the given key and store the length in <out-var>.
# If key does not define an array, then the length -1 is returned.
#
# NAME <name>  : Name of the YAML context.
# KEY <key>... : Name of key defining the list.
# <out-var>    : Name of output variable.
#
function(yaml_length out_var)
  cmake_parse_arguments(ARG_YAML "" "NAME" "KEY" ${ARGN})

  zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY)
  internal_yaml_context_required(NAME ${ARG_YAML_NAME})

  get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON)

  string(JSON type ERROR_VARIABLE error TYPE "${json_content}" ${ARG_YAML_KEY})
  if(type STREQUAL ARRAY)
    string(JSON subjson GET "${json_content}" ${ARG_YAML_KEY})
    string(JSON arraylength LENGTH "${subjson}")
    set(${out_var} ${arraylength} PARENT_SCOPE)
  elseif(type MATCHES ".*-NOTFOUND")
    set(${out_var} ${type} PARENT_SCOPE)
  else()
    message(WARNING "YAML key: ${ARG_YAML_KEY} is not an array.")
    set(${out_var} -1 PARENT_SCOPE)
  endif()
endfunction()

# Usage:
#   yaml_set(NAME <name> KEY <key>... VALUE <value>)
#   yaml_set(NAME <name> KEY <key>... [APPEND] LIST <value>...)
#
# Set a value or a list of values to given key.
#
# If setting a list of values, then APPEND can be specified to indicate that the
# list of values should be appended to the existing list identified with key(s).
#
# NAME <name>  : Name of the YAML context.
# KEY <key>... : Name of key.
# VALUE <value>: New value for the key.
# List <values>: New list of values for the key.
# APPEND       : Append the list of values to the list of values for the key.
#
function(yaml_set)
  cmake_parse_arguments(ARG_YAML "APPEND" "NAME;VALUE" "KEY;LIST" ${ARGN})

  zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY)
  zephyr_check_arguments_required_allow_empty(${CMAKE_CURRENT_FUNCTION} ARG_YAML VALUE LIST)
  zephyr_check_arguments_exclusive(${CMAKE_CURRENT_FUNCTION} ARG_YAML VALUE LIST)
  internal_yaml_context_required(NAME ${ARG_YAML_NAME})

  get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON)

  set(yaml_key_undefined ${ARG_YAML_KEY})
  foreach(k ${yaml_key_undefined})
    list(REMOVE_AT yaml_key_undefined 0)
    # We ignore any errors as we are checking for existence of the key, and
    # non-existing keys will throw errors but also set type to NOT-FOUND.
    string(JSON type ERROR_VARIABLE ignore TYPE "${json_content}" ${valid_keys} ${k})

    if(NOT type)
      list(APPEND yaml_key_create ${k})
      break()
    endif()
    list(APPEND valid_keys ${k})
  endforeach()

  list(REVERSE yaml_key_undefined)
  if(NOT "${yaml_key_undefined}" STREQUAL "")
    if(ARG_YAML_APPEND)
      set(json_string "[]")
    else()
      set(json_string "\"\"")
    endif()

    foreach(k ${yaml_key_undefined})
      set(json_string "{\"${k}\": ${json_string}}")
    endforeach()
    string(JSON json_content SET "${json_content}"
           ${valid_keys} ${yaml_key_create} "${json_string}"
    )
  endif()

  if(DEFINED ARG_YAML_LIST OR LIST IN_LIST ARG_YAML_KEYWORDS_MISSING_VALUES)
    if(NOT ARG_YAML_APPEND)
      string(JSON json_content SET "${json_content}" ${ARG_YAML_KEY} "[]")
    endif()

    string(JSON subjson GET "${json_content}" ${ARG_YAML_KEY})
    string(JSON index LENGTH "${subjson}")
    list(LENGTH ARG_YAML_LIST length)
    math(EXPR stop "${index} + ${length} - 1")
    if(NOT length EQUAL 0)
      foreach(i RANGE ${index} ${stop})
        list(POP_FRONT ARG_YAML_LIST value)
        string(JSON json_content SET "${json_content}" ${ARG_YAML_KEY} ${i} "\"${value}\"")
      endforeach()
    endif()
  else()
    string(JSON json_content SET "${json_content}" ${ARG_YAML_KEY} "\"${ARG_YAML_VALUE}\"")
  endif()

  zephyr_set(JSON "${json_content}" SCOPE ${ARG_YAML_NAME})
endfunction()

# Usage:
#   yaml_remove(NAME <name> KEY <key>...)
#
# Remove the KEY <key>... from the YAML context <name>.
#
# Several levels of keys can be given, for example:
# KEY build cmake command
#
# To remove the key 'command' underneath 'cmake' in the toplevel 'build'
#
# NAME <name>: Name of the YAML context.
# KEY <key>  : Name of key to remove.
#
function(yaml_remove)
  cmake_parse_arguments(ARG_YAML "" "NAME" "KEY" ${ARGN})

  zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY)
  internal_yaml_context_required(NAME ${ARG_YAML_NAME})

  get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON)
  string(JSON json_content REMOVE "${json_content}" ${ARG_YAML_KEY})

  zephyr_set(JSON "${json_content}" SCOPE ${ARG_YAML_NAME})
endfunction()

# Usage:
#   yaml_save(NAME <name> [FILE <file>])
#
# Write the YAML context <name> to the file which were given with the earlier
# 'yaml_load()' or 'yaml_create()' call.
#
# NAME <name>: Name of the YAML context
# FILE <file>: Path to file to write the context.
#              If not given, then the FILE property of the YAML context will be
#              used. In case both FILE is omitted and FILE property is missing
#              on the YAML context, then an error will be raised.
#
function(yaml_save)
  cmake_parse_arguments(ARG_YAML "" "NAME;FILE" "" ${ARGN})

  zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME)
  internal_yaml_context_required(NAME ${ARG_YAML_NAME})

  get_target_property(yaml_file ${ARG_YAML_NAME}_scope FILE)
  if(NOT yaml_file)
    zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} ARG_YAML FILE)
  endif()

  get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON)
  to_yaml("${json_content}" 0 yaml_out)

  if(DEFINED ARG_YAML_FILE)
    set(yaml_file ${ARG_YAML_FILE})
  else()
    get_property(yaml_file TARGET ${ARG_YAML_NAME}_scope PROPERTY FILE)
  endif()
  if(EXISTS ${yaml_file})
    FILE(RENAME ${yaml_file} ${yaml_file}.bak)
  endif()
  FILE(WRITE ${yaml_file} "${yaml_out}")
endfunction()

function(to_yaml json level yaml)
  if(level GREATER 0)
    math(EXPR level_dec "${level} - 1")
    set(indent_${level} "${indent_${level_dec}}  ")
  endif()

  string(JSON length LENGTH "${json}")
  if(length EQUAL 0)
    # Empty object
    return()
  endif()

  math(EXPR stop "${length} - 1")
  foreach(i RANGE 0 ${stop})
    string(JSON member MEMBER "${json}" ${i})

    string(JSON type TYPE "${json}" ${member})
    string(JSON subjson GET "${json}" ${member})
    if(type STREQUAL OBJECT)
      set(${yaml} "${${yaml}}${indent_${level}}${member}:\n")
      math(EXPR sublevel "${level} + 1")
      to_yaml("${subjson}" ${sublevel} ${yaml})
    elseif(type STREQUAL ARRAY)
      set(${yaml} "${${yaml}}${indent_${level}}${member}:")
      string(JSON arraylength LENGTH "${subjson}")
      if(${arraylength} LESS 1)
        set(${yaml} "${${yaml}} []\n")
      else()
        set(${yaml} "${${yaml}}\n")
        math(EXPR arraystop "${arraylength} - 1")
        foreach(i RANGE 0 ${arraystop})
          string(JSON item GET "${json}" ${member} ${i})
          set(${yaml} "${${yaml}}${indent_${level}} - ${item}\n")
        endforeach()
      endif()
    else()
      set(${yaml} "${${yaml}}${indent_${level}}${member}: ${subjson}\n")
    endif()
  endforeach()

  set(${yaml} ${${yaml}} PARENT_SCOPE)
endfunction()
