# - Use module for uMundo
# This file provides functions required to generate umundo services and serializers.
# Copy or add this file to your CMAKE_MODULE_PATH to use it. We rely on protobuf.
#
# Example Usage:
#
#		include(UseUMundo)
#
#		file(GLOB_RECURSE PROTOBUF_INTERFACES interfaces/protobuf/*.proto)
#		UMUNDO_PROTOBUF_GENERATE_CPP_S11N(PROTO_SRCS PROTO_HDRS ${PROTOBUF_INTERFACES})
#		include_directories(${CMAKE_BINARY_DIR}/protobuf/generated)
#		list(APPEND UMUNDOS11N_HEADER_FILES ${PROTO_HDRS})	
#		list(APPEND UMUNDOS11N_FILES ${PROTO_SRCS})	
#
# PROTO_SRCS and PROTO_HDRS will contain the paths of generated serializers and deserializers
# for all the .proto files in "interfaces/protobuf/*.proto".
#
# Defines the following functions:
#
# UMUNDO_PROTOBUF_GENERATE_CPP_[S11N|RPC]()
#   SRCS = Variable to define with autogenerated
#          source files
#   HDRS = Variable to define with autogenerated
#          header files
#   ARGN = proto files
#
# Defines the following variables:
#
# UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE           The path to the umundo protoc plugin for CPP
# UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE_DEP       The name of the target which builds the umundo protoc plugin
# UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE          The path to the umundo protoc plugin for Java
# UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE_DEP      The name of the target which builds the umundo protoc plugin
#

# try hard to find the protoc rpc plugins
set(UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE)
set(UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE_DEP)
set(UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE)
set(UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE_DEP)

if (NOT CMAKE_CROSSCOMPILING AND CMAKE_PROJECT_NAME MATCHES "umundo")
	if (WIN32)
		set(UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/protoc-umundo-cpp-rpc.exe")
		set(UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/protoc-umundo-java-rpc.exe")
	else()
		set(UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/protoc-umundo-cpp-rpc")
		set(UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/protoc-umundo-java-rpc")
	endif()
	set(UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE_DEP "protoc-umundo-cpp-rpc")
	set(UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE_DEP "protoc-umundo-java-rpc")
endif()

if (NOT UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE)
	find_program(UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE 
		NAMES protoc-umundo-cpp-rpc protoc-umundo-cpp-rpc.exe
		PATHS 
			/usr/local/bin 
			/opt/local/bin
			/usr/bin
			C:\\Program\ Files\ \(x86\)\\uMundo\\bin
		ENV UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE
	)
endif()

if (NOT UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE)
	find_program(UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE 
		NAMES protoc-umundo-java-rpc protoc-umundo-java-rpc.exe
		PATHS 
			/usr/local/bin 
			/opt/local/bin
			/usr/bin
			C:\\Program\ Files\ \(x86\)\\uMundo\\bin
		ENV UMUNDO_PROTOBUF_JAVA_RPC_EXECUTABLE
	)
endif()

#########################################################################
# Redefine PROTOBUF_GENERATE_CPP macro to allow subdirectories and objc
#########################################################################

function(UMUNDO_PROTOBUF_GENERATE_CPP_RPC SRCS HDRS)
  set(${SRCS})
  set(${HDRS})
	UMUNDO_PROTOBUF_GENERATE_CPP("RPC" ${SRCS} ${HDRS} ${ARGN})
  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
	set(${SRCS} ${${SRCS}} PARENT_SCOPE)
	set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()

function(UMUNDO_PROTOBUF_GENERATE_CPP_S11N SRCS HDRS)
  set(${SRCS})
  set(${HDRS})
	UMUNDO_PROTOBUF_GENERATE_CPP("S11N" ${SRCS} ${HDRS} ${ARGN})
  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
	set(${SRCS} ${${SRCS}} PARENT_SCOPE)
	set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()

function(UMUNDO_PROTOBUF_GENERATE_CPP RPC_OR_S11N SRCS HDRS)
  find_package(Protobuf REQUIRED)
	file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/protobuf/generated)
	
  if(NOT ARGN)
    message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
    return()
  endif(NOT ARGN)

  if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
    # Create an include path for each file specified
    foreach(FIL ${ARGN})
      get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
      get_filename_component(ABS_PATH ${ABS_FIL} PATH)
      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
      if(${_contains_already} EQUAL -1)
          list(APPEND _protobuf_include_path -I ${ABS_PATH})
      endif()
    endforeach()
  else()
    set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
  endif()

  if(DEFINED PROTOBUF_IMPORT_DIRS)
    foreach(DIR ${PROTOBUF_IMPORT_DIRS})
      get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
      if(${_contains_already} EQUAL -1)
          list(APPEND _protobuf_include_path -I ${ABS_PATH})
      endif()
    endforeach()
  endif()

  set(${SRCS})
  set(${HDRS})
  foreach(FIL ${ARGN})
    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
    get_filename_component(FIL_WE ${FIL} NAME_WE)

    list(APPEND ${SRCS} "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.cc")
    list(APPEND ${HDRS} "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.h")

#		if (RPC_OR_S11N MATCHES "S11N")
			add_custom_command(
				OUTPUT "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.cc"
				       "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.h"
				       "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.desc"
				COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
				ARGS --include_imports --descriptor_set_out=${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.desc --cpp_out ${CMAKE_BINARY_DIR}/protobuf/generated ${_protobuf_include_path} ${ABS_FIL}
				DEPENDS ${ABS_FIL}
				COMMENT "Running C++ protocol buffer compiler on ${FIL}"
				VERBATIM 
			)
	   	
    	list(APPEND ${SRCS} "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.cc")
    	list(APPEND ${HDRS} "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.pb.h")
#		endif()

		if (RPC_OR_S11N MATCHES "RPC")
			if (NOT UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE AND NOT UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE_DEP)
				message(FATAL_ERROR "Could not find protoc-umundo-cpp-rpc")
				RETURN()
			endif()

			add_custom_command(
				OUTPUT "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.rpc.pb.cc"
				       "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.rpc.pb.h"
				COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
				ARGS --plugin=protoc-gen-cpp_rpc=${UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE} --cpp_rpc_out ${CMAKE_BINARY_DIR}/protobuf/generated ${_protobuf_include_path} ${ABS_FIL}
				DEPENDS ${ABS_FIL} ${UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE_DEP}
				COMMENT "Running C++ RPC protocol buffer compiler on ${FIL}"
				VERBATIM 
			)

    	list(APPEND ${SRCS} "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.rpc.pb.cc")
    	list(APPEND ${HDRS} "${CMAKE_BINARY_DIR}/protobuf/generated/${FIL_WE}.rpc.pb.h")
		endif()
  endforeach()

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

endfunction()

MARK_AS_ADVANCED(UMUNDO_PROTOBUF_CPP_RPC_EXECUTABLE_DEP)

