# Copyright (c) 2018 Cisco and/or its affiliates.
# 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.

# Set the CMP0116 policy
if(POLICY CMP0116)
    cmake_policy(SET CMP0116 NEW)
endif()

##############################################################################
# API
##############################################################################
function(vpp_generate_api_c_header file)
  set (output_name ${CMAKE_CURRENT_BINARY_DIR}/${file}.h)
  set (dependency_file ${CMAKE_CURRENT_BINARY_DIR}/${file}.d)
  get_filename_component(output_dir ${output_name} DIRECTORY)
  if(NOT VPP_APIGEN)
    set(VPP_APIGEN ${CMAKE_SOURCE_DIR}/tools/vppapigen/vppapigen)
    set(VPPAPIGEN_SUBMODULES
      ${CMAKE_SOURCE_DIR}/tools/vppapigen/vppapigen_c.py
      ${CMAKE_SOURCE_DIR}/tools/vppapigen/vppapigen_json.py
    )
  endif()
  if (VPP_INCLUDE_DIR)
    set(includedir "--includedir" ${VPP_INCLUDE_DIR})
  endif()

  set(OUTPUT_HEADERS
    "${CMAKE_CURRENT_BINARY_DIR}/${file}.h"
    "${CMAKE_CURRENT_BINARY_DIR}/${file}_fromjson.h"
    "${CMAKE_CURRENT_BINARY_DIR}/${file}_tojson.h"
    "${CMAKE_CURRENT_BINARY_DIR}/${file}_enum.h"
    "${CMAKE_CURRENT_BINARY_DIR}/${file}_types.h"
    "${CMAKE_CURRENT_BINARY_DIR}/${file}.c"
    "${CMAKE_CURRENT_BINARY_DIR}/${file}_test.c"
    "${CMAKE_CURRENT_BINARY_DIR}/${file}_test2.c"
  )

  get_filename_component(barename ${file} NAME)

# Define a variable for common apigen arguments
set(COMMON_ARGS
  OUTPUT ${OUTPUT_HEADERS}
  COMMAND mkdir -p ${output_dir}
  COMMAND ${PYENV} ${VPP_APIGEN}
  ARGS ${includedir} --includedir ${CMAKE_SOURCE_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/${file} --outputdir ${output_dir} --output ${output_name} -MF ${dependency_file}
  DEPENDS ${VPP_APIGEN} ${CMAKE_CURRENT_SOURCE_DIR}/${file} ${VPPAPIGEN_SUBMODULES}
  COMMENT "Generating API header ${output_name}"
)

if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.20")
  add_custom_command (
    ${COMMON_ARGS}
    DEPFILE ${dependency_file}
  )
else()
  message(WARNING "Your CMake version does not support DEPFILE. Consider upgrading to CMake 3.20 or later for improved dependency handling.")
  add_custom_command (
    ${COMMON_ARGS}
  )
endif()
  set(t ${barename}_deps)

  if (NOT TARGET ${t})
    add_custom_target(${t} ALL DEPENDS ${OUTPUT_HEADERS})
    add_dependencies(api_headers ${t})
  endif()

endfunction()

function(vpp_generate_api_json_header file dir component)
  set (output_name ${CMAKE_CURRENT_BINARY_DIR}/${file}.json)
  get_filename_component(output_dir ${output_name} DIRECTORY)
  if(NOT VPP_APIGEN)
     set(VPP_APIGEN ${CMAKE_SOURCE_DIR}/tools/vppapigen/vppapigen)
  endif()
  if (VPP_INCLUDE_DIR)
    set(includedir "--includedir" ${VPP_INCLUDE_DIR})
  endif()
  add_custom_command (OUTPUT ${output_name}
    COMMAND mkdir -p ${output_dir}
    COMMAND ${PYENV} ${VPP_APIGEN}
    ARGS ${includedir} --includedir ${CMAKE_SOURCE_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/${file} JSON --outputdir ${output_dir} --output ${output_name}
    DEPENDS ${VPP_APIGEN} ${CMAKE_CURRENT_SOURCE_DIR}/${file}
    COMMENT "Generating API header ${output_name}"
  )
  install(
    FILES ${output_name}
    DESTINATION ${CMAKE_INSTALL_DATADIR}/vpp/api/${dir}/
    COMPONENT ${component}
  )
endfunction()

##############################################################################
# VPP-API
##############################################################################
function(vpp_generate_vapi_c_header f)
  get_filename_component(output ${f}.vapi.h NAME)
  set (output_name ${VPP_BINARY_DIR}/vpp-api/vapi/${output})
  if(NOT VPP_VAPI_C_GEN)
    set(VPP_VAPI_C_GEN ${CMAKE_SOURCE_DIR}/vpp-api/vapi/vapi_c_gen.py)
    set(VPP_VAPI_C_GEN_DEPENDS
        ${CMAKE_SOURCE_DIR}/vpp-api/vapi/vapi_c_gen.py
        ${CMAKE_SOURCE_DIR}/vpp-api/vapi/vapi_json_parser.py
    )
  endif()

  # C VAPI Headers
  set(input ${CMAKE_CURRENT_BINARY_DIR}/${f}.json)
  add_custom_command(
    OUTPUT ${output_name}
    WORKING_DIRECTORY ${VPP_BINARY_DIR}/vpp-api/vapi
    COMMAND ${PYENV} ${VPP_VAPI_C_GEN}
    ARGS --remove-path ${input}
    DEPENDS ${input} ${VPP_VAPI_C_GEN_DEPENDS}
    COMMENT "Generating VAPI C header ${output_name}"
  )
  install(
    FILES ${output_name}
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/vapi
    COMPONENT vpp-dev
  )
endfunction ()

function (vpp_generate_vapi_cpp_header f)
  get_filename_component(output ${f}.vapi.hpp NAME)
  set (output_name ${VPP_BINARY_DIR}/vpp-api/vapi/${output})
  if(NOT VPP_VAPI_CPP_GEN)
    set(VPP_VAPI_CPP_GEN ${CMAKE_SOURCE_DIR}/vpp-api/vapi/vapi_cpp_gen.py)
    set(VPP_VAPI_CPP_GEN_DEPENDS
        ${CMAKE_SOURCE_DIR}/vpp-api/vapi/vapi_cpp_gen.py
        ${CMAKE_SOURCE_DIR}/vpp-api/vapi/vapi_json_parser.py
    )
  endif()
  # C++ VAPI Headers
  set(input ${CMAKE_CURRENT_BINARY_DIR}/${f}.json)
  add_custom_command(
    OUTPUT ${output_name}
    WORKING_DIRECTORY ${VPP_BINARY_DIR}/vpp-api/vapi
    COMMAND ${PYENV} ${VPP_VAPI_CPP_GEN}
    ARGS --gen-h-prefix=vapi --remove-path ${input}
    DEPENDS ${input} ${VPP_VAPI_CPP_GEN_DEPENDS}
    COMMENT "Generating VAPI C++ header ${output_name}"
  )
  install(
    FILES ${output_name}
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/vapi
    COMPONENT vpp-dev
  )
endfunction ()


##############################################################################
# generate the .h and .json files for a .api file
#  @param file - the name of the .api
#  @param dir  - the install directory under ROOT/share/vpp/api to place the
#                generated .json file
##############################################################################
function(vpp_generate_api_header file dir component)
  vpp_generate_api_c_header (${file})
  vpp_generate_api_json_header (${file} ${dir} ${component})
  vpp_generate_vapi_c_header (${file})
  vpp_generate_vapi_cpp_header (${file})
endfunction()

function(vpp_add_api_files name dir component)
  unset(header_files)
  set(target ${name}_api_headers)
  file(RELATIVE_PATH rpath ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
  foreach(file ${ARGN})
    vpp_generate_api_header (${file} ${dir} ${component})
    # Basic api headers get installed in a subdirectory according to
    # their component name, but vapi is expected to be found directly under
    # "vapi". Both by in-source components (e.g. vpp-api/vapi/vapi.c), and
    # out-of-tree plugins use #include <vapi/component.api.vapi.h>.
    # ${file} contains the subdirectory, so strip it here.
    file(MAKE_DIRECTORY ${VPP_BINARY_DIR}/vpp-api/vapi)
    get_filename_component(name ${file} NAME)
    list(APPEND header_files
      ${file}.h
      ${file}_enum.h
      ${file}_types.h
      ${file}.json
      ${VPP_BINARY_DIR}/vpp-api/vapi/${name}.vapi.h
      ${VPP_BINARY_DIR}/vpp-api/vapi/${name}.vapi.hpp
    )
  endforeach()
  add_custom_target(${target} DEPENDS ${header_files})
  add_dependencies(api_headers ${target})
endfunction()

add_custom_target(api_headers
  DEPENDS vlibmemory_api_headers vnet_api_headers vpp_api_headers vlib_api_headers
)
add_custom_target(vapi_headers
)
