# 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.

##############################################################################
# API
##############################################################################
function(vpp_generate_api_c_header file)
  set (output_name ${CMAKE_CURRENT_BINARY_DIR}/${file}.h)
  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()

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

  add_custom_command (
    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}
    DEPENDS ${VPP_APIGEN} ${CMAKE_CURRENT_SOURCE_DIR}/${file}
    COMMENT "Generating API header ${output_name}"
  )
  get_filename_component(barename ${file} NAME)
  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 share/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 include/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 include/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.
    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
)
