# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

macro(dbg_message)
  if(TEACLAVE_CMAKE_DBG)
    message("${ARGN}")
  endif()
endmacro()

macro(SET_STRVAR_FROM_ENV_OR var default_val docstring)
  if(NOT "$ENV{${var}}" STREQUAL "")
    set(${var}
        "$ENV{${var}}"
        CACHE STRING "${docstring}")
  else()
    set(${var}
        "${default_val}"
        CACHE STRING "${docstring}")
  endif()
endmacro()

function(check_sgx_sdk)
  if(NOT IS_DIRECTORY "${SGX_SDK}")
    message(
      FATAL_ERROR
        "SGX SDK not found at ${SGX_SDK}, please adjust the SGX_SDK env or the CMake config."
    )
  endif()
endfunction()

function(init_submodules)
  if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
    # Update submodules as needed
    if(GIT_SUBMODULE)
      message(STATUS "Submodule update")
      execute_process(
        COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        RESULT_VARIABLE GIT_SUBMOD_RESULT)
      if(NOT GIT_SUBMOD_RESULT EQUAL "0")
        message(
          FATAL_ERROR
            "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules"
        )
      endif()
      # Patch WAMR after pulling
      if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/wasm-micro-runtime/product-mini/platforms/teaclave-sgx/CMakeLists.txt")
        execute_process(
          COMMAND 
            patch -N -p1
          INPUT_FILE "../wamr.patch"
          WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/wasm-micro-runtime
          )
      endif()
    endif()
  endif()

  if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/crates-io"
     OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/crates-sgx"
     OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/mesapy"
     OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/rust-sgx-sdk"
     OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/wasm-micro-runtime")
    message(
      FATAL_ERROR
        "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again."
    )
  endif()
endfunction()

macro(rm_trailing_enclave src_str dest_name)
  string(REGEX REPLACE "_enclave$" "" ${dest_name} ${src_str})
endmacro()

# add_cargo_build_target(package_name [TARGET_NAME target_name] # default to
# cg_${package_name} TOML_DIR toml_dir TARGET_DIR target_dir [DEPENDS [dep]...]
# [NOT_SET_COMMON_ENV] [EXTRA_CARGO_FLAGS flg...] )
function(add_cargo_build_target package_name)
  set(options NOT_SET_COMMON_ENV)
  set(oneValueArgs TARGET_NAME TOML_DIR TARGET_DIR INSTALL_DIR
                   EXTRA_CARGO_FLAGS)
  set(multiValueArgs DEPENDS)
  cmake_parse_arguments(MTEE "${options}" "${oneValueArgs}" "${multiValueArgs}"
                        ${ARGN})

  if(DEFINED MTEE_TARGET_NAME)
    set(_target_name ${MTEE_TARGET_NAME})
  else()
    set(_target_name cg_${package_name})
  endif()

  if(DEFINED MTEE_INSTALL_DIR)
    set(_copy_dir ${MTEE_INSTALL_DIR})
  else()
    set(_copy_dir ${TEACLAVE_INSTALL_DIR})
  endif()

  if(MTEE_NOT_SET_COMMON_ENV)
    set(_envs)
  else()
    set(_envs ${TEACLAVE_COMMON_ENVS})
  endif()

  if(DEFINED MTEE_DEPENDS)
    set(_depends DEPENDS ${MTEE_DEPENDS})
  else()
    set(_depends)
  endif()

  add_custom_target(
    ${_target_name} ALL
    COMMAND
      ${CMAKE_COMMAND} -E env ${_envs} RUSTFLAGS=${RUSTFLAGS}
      ${MT_SCRIPT_DIR}/cargo_build_ex.sh -p ${package_name} --target-dir
      ${MTEE_TARGET_DIR} ${CARGO_BUILD_FLAGS} ${MTEE_EXTRA_CARGO_FLAGS} && cp
      ${MTEE_TARGET_DIR}/${TARGET}/${package_name} ${_copy_dir} ${_depends}
    COMMENT "Building ${_target_name}"
    WORKING_DIRECTORY ${MTEE_TOML_DIR})
endfunction()

# add_cargo_build_dylib_target(package_name [TARGET_NAME target_name] # default to
# cg_${package_name} TOML_DIR toml_dir TARGET_DIR target_dir [DEPENDS [dep]...]
# [NOT_SET_COMMON_ENV] [EXTRA_CARGO_FLAGS flg...] )
function(add_cargo_build_dylib_staticlib_target package_name)
  set(options NOT_SET_COMMON_ENV)
  set(oneValueArgs TARGET_NAME TOML_DIR TARGET_DIR)
  set(multiValueArgs DEPENDS EXTRA_CARGO_FLAGS)
  cmake_parse_arguments(MTEE "${options}" "${oneValueArgs}" "${multiValueArgs}"
                        ${ARGN})

  if(DEFINED MTEE_TARGET_NAME)
    set(_target_name ${MTEE_TARGET_NAME})
  else()
    set(_target_name cg_${package_name})
  endif()

  if(MTEE_NOT_SET_COMMON_ENV)
    set(_envs)
  else()
    set(_envs ${TEACLAVE_COMMON_ENVS})
  endif()

  if(DEFINED MTEE_DEPENDS)
    set(_depends DEPENDS ${MTEE_DEPENDS})
  else()
    set(_depends)
  endif()

  add_custom_target(
    ${_target_name} ALL
    COMMAND
      ${CMAKE_COMMAND} -E env ${_envs} RUSTFLAGS=${RUSTFLAGS}
      ${MT_SCRIPT_DIR}/cargo_build_ex.sh -p ${package_name} --target-dir
      ${MTEE_TARGET_DIR} ${CARGO_BUILD_FLAGS} ${MTEE_EXTRA_CARGO_FLAGS} &&
      cp ${MTEE_TARGET_DIR}/${TARGET}/lib${package_name}.so
      ${MTEE_TARGET_DIR}/${TARGET}/lib${package_name}.a
      ${TEACLAVE_LIB_INSTALL_DIR} ${_depends}
    COMMENT "Building ${_target_name} as dynamic and static libraries"
    WORKING_DIRECTORY ${MTEE_TOML_DIR})
endfunction()

# add_sgx_build_target(sgx_lib_path pkg_name [DEPENDS [dep]...] [INSTALL_DIR
# dir] [EXTRA_CARGO_FLAGS flg...] )
function(add_sgx_build_target sgx_lib_path pkg_name)
  set(options)
  set(oneValueArgs INSTALL_DIR EDL_LIB_NAME)
  set(multiValueArgs DEPENDS EXTRA_CARGO_FLAGS)
  cmake_parse_arguments(MTEE "${options}" "${oneValueArgs}" "${multiValueArgs}"
                        ${ARGN})

  if(DEFINED MTEE_DEPENDS)
    set(_depends DEPENDS ${MTEE_DEPENDS})
  else()
    set(_depends)
  endif()

  if(DEFINED MTEE_INSTALL_DIR)
    set(_copy_dir ${MTEE_INSTALL_DIR})
  else()
    set(_copy_dir ${TEACLAVE_INSTALL_DIR})
  endif()

  if(DEFINED MTEE_EDL_LIB_NAME)
    set(_edl_lib_name ${MTEE_EDL_LIB_NAME})
  else()
    set(_edl_lib_name)
  endif()

  rm_trailing_enclave(${pkg_name} pkg_name_no_enclave)

  set(_target_name ${SGXLIB_PREFIX}-${pkg_name_no_enclave})

  if(pkg_name_no_enclave MATCHES "_tests$")
    set(RUSTFLAGS "${RUSTFLAGS} --cfg test_mode")
  endif()

  if(pkg_name_no_enclave MATCHES "_tests$" AND CMAKE_BUILD_TYPE_LOWER STREQUAL
                                               "release")
    set(_enclave_info "/dev/null")
  else()
    set(_enclave_info "${TEACLAVE_OUT_DIR}/${pkg_name}_info.toml")
  endif()

  if(pkg_name_no_enclave MATCHES "_tool$")
    set(_enclave_info "/dev/null")
  endif()

  add_custom_target(
    ${_target_name} ALL
    COMMAND
      ${CMAKE_COMMAND} -E env ${TEACLAVE_COMMON_ENVS} RUSTFLAGS=${RUSTFLAGS}
      ${MT_SCRIPT_DIR}/cargo_build_ex.sh -p ${pkg_name} --target-dir
      ${TRUSTED_TARGET_DIR} ${CARGO_BUILD_FLAGS} ${SGX_ENCLAVE_FEATURES}
      ${MTEE_EXTRA_CARGO_FLAGS}
    COMMAND
      ${CMAKE_COMMAND} -E env ${TARGET_SGXLIB_ENVS}
      SGX_COMMON_CFLAGS=${STR_SGX_COMMON_CFLAGS} CUR_PKG_NAME=${pkg_name}
      CUR_PKG_PATH=${sgx_lib_path} CUR_INSTALL_DIR=${_copy_dir}
      ${MT_SCRIPT_DIR}/sgx_link_sign.sh ${_edl_lib_name} ${_depends}
    COMMAND
      cat ${TEACLAVE_OUT_DIR}/${pkg_name}.meta.txt | python
      ${MT_SCRIPT_DIR}/gen_enclave_info_toml.py ${pkg_name_no_enclave} >
      ${_enclave_info}
    COMMENT "Building ${_target_name}, enclave info to ${_enclave_info}"
    WORKING_DIRECTORY ${MT_SGXLIB_TOML_DIR})
endfunction()

function(add_enclave_sig_target_n_hooks)
  # add a target to generate enclave sig files
  add_custom_target(
    update_sig ALL
    COMMAND ${TEACLAVE_COMMON_ENVS} ${MT_SCRIPT_DIR}/gen_enclave_sig.sh
    COMMENT "Generating enclave signatures..."
    DEPENDS ${SGXLIB_TARGETS})

  # Hook the convenience targets for SGX modules so manually `make teaclave_execution_service/teaclave_frontend_service/...`
  # will trigger updating enclave sig files
  foreach(sgx_module ${SGX_MODULES})
    add_custom_command(
      TARGET ${sgx_module}
      POST_BUILD
      COMMENT "Updating enclave signatures..."
      COMMAND ${TEACLAVE_COMMON_ENVS} ${MT_SCRIPT_DIR}/gen_enclave_sig.sh)
  endforeach()
endfunction()

function(join_string values glue out)
  string(REGEX REPLACE "([^\\]|^);" "\\1${glue}" _res "${values}")
  string(REGEX REPLACE "[\\](.)" "\\1" _res "${_res}")
  set(${out}
      "${_res}"
      PARENT_SCOPE)
endfunction()

function(generate_env_file)
  set(envs ${TEACLAVE_COMMON_ENVS})
  list(FILTER envs INCLUDE REGEX "TEACLAVE_PROJECT_ROOT|TEACLAVE_CFG_DIR|\
TEACLAVE_BUILD_CFG_DIR|TEACLAVE_OUT_DIR|TEACLAVE_AUDITORS_DIR")
  # add extra env vars
  list(APPEND envs "RUST_LOG=info" "RUST_BACKTRACE=1")
  join_string("${envs}" "\nexport " env_file)
  string(PREPEND env_file "export ")
  string(APPEND env_file "\n")
  file(WRITE ${PROJECT_BINARY_DIR}/environment ${env_file})
  message(STATUS "====== ${PROJECT_BINARY_DIR}/environment GENERATED ======")
endfunction()

function(gen_convenience_targets)
  # add a target with the same name for each unix_module
  foreach(unix_module ${UNIX_APPS})
    add_custom_target(${unix_module} DEPENDS ${UNIXAPP_PREFIX}-${unix_module})
  endforeach()

  # add a target with the same name for each sgx_module (build sgxlib+sgxapp)
  foreach(sgx_module ${SGX_MODULES})
    add_custom_target(${sgx_module} DEPENDS ${SGXAPP_PREFIX}-${sgx_module}
                                            ${SGXLIB_PREFIX}-${sgx_module})
  endforeach()
endfunction()

function(new_list_with_prefix new_list_name prefix)
  set(_new_list)
  foreach(item ${ARGN})
    string(PREPEND item ${prefix})
    set(_new_list ${_new_list} ${item})
  endforeach()
  set(${new_list_name}
      ${_new_list}
      PARENT_SCOPE)
endfunction()

function(check_exe_dependencies)
  foreach(exe ${ARGN})
    execute_process(COMMAND bash -c "type ${exe}" OUTPUT_QUIET ERROR_QUIET
                    RESULT_VARIABLE _res)
    if(_res)
      message(
        FATAL_ERROR
          "Teaclave depends on \"${exe}\" but the command was not found. \
Please install the dependency and retry.")
    endif()
  endforeach()
endfunction()

function(parse_cargo_packages pkg_names)
  set(options)
  set(oneValueArgs CARGO_TOML_PATH PKG_PATHS CATEGORIES EDL_NAMES)
  set(multiValueArgs)

  cmake_parse_arguments(MTEE "${options}" "${oneValueArgs}" "${multiValueArgs}"
                        ${ARGN})

  set(_output)
  set(err)

  execute_process(
    COMMAND python ${PROJECT_SOURCE_DIR}/cmake/scripts/parse_cargo_packages.py
            ${MTEE_CARGO_TOML_PATH} ${PROJECT_SOURCE_DIR}
    OUTPUT_VARIABLE _output
    ERROR_VARIABLE err)

  if(NOT (err STREQUAL ""))
    message(FATAL_ERROR "failed to load packages: ${err}")
  endif()

  string(REGEX REPLACE "\n" ";" _out_list ${_output})
  list(LENGTH _out_list LLEN)

  if(DEFINED MTEE_EDL_NAMES)
    list(GET _out_list 3 _edl_names)
    string(REPLACE ":" ";" _edl_names ${_edl_names})
    set(${MTEE_EDL_NAMES}
        ${_edl_names}
        PARENT_SCOPE)
    dbg_message("${MTEE_EDL_NAMES}=${_edl_names}\n")
  endif()

  if(DEFINED MTEE_CATEGORIES)
    list(GET _out_list 2 _categories)
    string(REPLACE ":" ";" _categories ${_categories})
    set(${MTEE_CATEGORIES}
        ${_categories}
        PARENT_SCOPE)
    dbg_message("${MTEE_CATEGORIES}=${_categories}\n")
  endif()

  if(DEFINED MTEE_PKG_PATHS)
    list(GET _out_list 1 _pkg_paths)
    string(REPLACE ":" ";" _pkg_paths ${_pkg_paths})
    set(${MTEE_PKG_PATHS}
        ${_pkg_paths}
        PARENT_SCOPE)
    dbg_message("${MTEE_PKG_PATHS}=${_pkg_paths}\n")
  endif()

  # level up the local variable to its parent scope
  list(GET _out_list 0 _pkg_names)
  string(REPLACE ":" ";" _pkg_names ${_pkg_names})
  set(${pkg_names}
      ${_pkg_names}
      PARENT_SCOPE)
  dbg_message("${pkg_names}=${_pkg_names}\n")
endfunction()
