# Based on:
# https://github.com/isn-/capnproto/blob/54c63a420ac3cdf614cb501864c7ef551275efa3/cmake/capnpc.cmake

# inspired by google's protobuf cmake module
#  ====================================================================
#
# CAPNP_COMPILE (public function)
#   First parameter = Variable to define with autogenerated source files
#   Optional HEADERS = Variable to define with autogenerated header files
#   Optional SRC_PREFIX = --src-prefix [default = ${CMAKE_CURRENT_SOURCE_DIR}]
#   Optional NO_STD_IMPORT = --no-standard-import
#   Optional IMPORT = --import-path
#   Optional OUTPUT_DIR = Output directory [default = ${CMAKE_CURRENT_BINARY_DIR}]
#   Optional PLUGIN = Plugin executable [default = ${CAPNP_PLUGIN_CXX}]
#   Unbound parameters = Source files
#
#  ====================================================================

include(CMakeParseArguments)

function(CAPNP_COMPILE SRCS)
  set(OPTIONS NO_STD_IMPORT)
  set(ONE_VAL_ARGS PLUGIN OUTPUT_DIR SRC_PREFIX HEADERS)
  set(MULTI_VAL_ARGS IMPORT)
  cmake_parse_arguments(ARG "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})

  set(SOURCES ${ARG_UNPARSED_ARGUMENTS})

  if(NOT ARG_PLUGIN)
    set(ARG_PLUGIN ${CAPNP_PLUGIN_CXX})
  endif()

  set(CAPNP_ARGS "--output=${ARG_PLUGIN}")

  if(ARG_OUTPUT_DIR)
    set(CAPNP_ARGS "${CAPNP_ARGS}:${ARG_OUTPUT_DIR}")
  else()
    set(ARG_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
  endif()

  if(ARG_NO_STD_IMPORT)
    list(APPEND CAPNP_ARGS "--no-standard-import")
  endif()

  if(ARG_SRC_PREFIX)
    get_filename_component(ABS_PREFIX ${ARG_SRC_PREFIX} ABSOLUTE)
    list(APPEND CAPNP_ARGS "--src-prefix=${ABS_PREFIX}")
  else()
    set(ARG_SRC_PREFIX ${CMAKE_CURRENT_SOURCE_DIR})
    list(APPEND CAPNP_ARGS "--src-prefix=${CMAKE_CURRENT_SOURCE_DIR}")
  endif()

  foreach(IMPORT ${ARG_IMPORT})
    get_filename_component(ABS_IMPORT ${IMPORT} ABSOLUTE)
    list(APPEND CAPNP_ARGS "--import-path=${ABS_IMPORT}")
  endforeach()

  if(ARG_HEADERS)
    set(HDRS ${ARG_HEADERS})
  else()
    set(HDRS "_")
  endif()

  set(${SRCS})
  set(${HDRS})
  foreach(FIL ${SOURCES})
    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
    string(REPLACE ${ARG_SRC_PREFIX} "" OUT_FIL ${FIL})

    list(APPEND ${SRCS} "${ARG_OUTPUT_DIR}/${OUT_FIL}.c++")
    list(APPEND ${HDRS} "${ARG_OUTPUT_DIR}/${OUT_FIL}.h")

    add_custom_command(
      OUTPUT "${ARG_OUTPUT_DIR}/${OUT_FIL}.c++"
             "${ARG_OUTPUT_DIR}/${OUT_FIL}.h"
      COMMAND  ${CAPNP_EXECUTABLE}
      ARGS compile ${CAPNP_ARGS} ${ABS_FIL}
      DEPENDS ${ABS_FIL} ${ARG_PLUGIN}
      COMMENT "Compiling Cap'n Proto file ${FIL}"
      VERBATIM)
  endforeach()

  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
  set(${SRCS} ${${SRCS}} PARENT_SCOPE)

  if(ARG_HEADERS)
    set(${HDRS} ${${HDRS}} PARENT_SCOPE)
  endif()
endfunction()
