macro(jomw_parse_arguments target_type_name)
  cmake_parse_arguments(JOMW_ADD
    ""
    "PACKAGE_NAME"
    "SOURCES"
    "${ARGN}")

  # Set CMake target name
  set(target_name "${jomw_target_name}_${target_type_name}")
endmacro()

macro(jomw_add_dynamic_target target_name support_target_name target_sources)
  # Create library target
  add_library(${target_name} SHARED ${target_sources})

  # C++14 required
  set_target_properties(${target_name} PROPERTIES CXX_STANDARD 14)

  # Link whole-archive support target
  target_link_libraries(${target_name} PRIVATE -Wl,--whole-archive ${support_target_name} -Wl,--no-whole-archive)

  # Add include directories read from the core library
  get_target_property(_jomw_support_include_directories ${support_target_name} INTERFACE_INCLUDE_DIRECTORIES)
  message(STATUS "${support_target_name} interface: ${_jomw_support_include_directories}")
  target_include_directories(${target_name} PUBLIC ${_jomw_support_include_directories})
endmacro()

function(jomw_add_julia_target jomw_target_name)
  # Parse arguments
  jomw_parse_arguments(julia ${ARGN})

  # Create library target
  jomw_add_dynamic_target(${target_name} ${JOMW_NAMESPACE_PREFIX}julia "${JOMW_ADD_SOURCES}")

  if(JOMW_ADD_PACKAGE_NAME)
    # Set target file name
    message(STATUS "Prefix: ${CMAKE_SHARED_LIBRARY_PREFIX}")
    set(_JOMW_TARGET ${CMAKE_SHARED_LIBRARY_PREFIX}${target_name})

    # Create module file
    configure_file(${JOMW_FUNCTIONS_BASE_DIR}/Module.jl.in
      ${CMAKE_CURRENT_BINARY_DIR}/${JOMW_ADD_PACKAGE_NAME}.jl @ONLY)
  endif()
endfunction()

function(jomw_add_mathematica_target jomw_target_name)
  # Parse arguments
  jomw_parse_arguments(mathematica ${ARGN})

  # Create library target
  jomw_add_dynamic_target(${target_name} ${JOMW_NAMESPACE_PREFIX}mathematica "${JOMW_ADD_SOURCES}")

  if(JOMW_ADD_PACKAGE_NAME)
    set(JOMW_MATHEMATICA_TARGET_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${JOMW_ADD_PACKAGE_NAME})
    message(STATUS "Installing Mathematica target to ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR}")

    # Create package directory structure
    file(MAKE_DIRECTORY ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR})
    file(MAKE_DIRECTORY ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR}/Kernel)
    file(MAKE_DIRECTORY ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR}/LibraryResources)
    file(MAKE_DIRECTORY ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR}/LibraryResources/${Mathematica_SYSTEM_ID})

    # Deploy package files
    configure_file(${JOMW_FUNCTIONS_BASE_DIR}/MathematicaPackage.m.in
      ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR}/${JOMW_ADD_PACKAGE_NAME}.m @ONLY)
    configure_file(${JOMW_FUNCTIONS_BASE_DIR}/MathematicaPackageInit.m.in
      ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR}/Kernel/init.m @ONLY)

    # Build to the target file
    set_target_properties(${target_name} PROPERTIES
      LIBRARY_OUTPUT_DIRECTORY ${JOMW_MATHEMATICA_TARGET_PACKAGE_DIR}/LibraryResources/${Mathematica_SYSTEM_ID})
  endif()
endfunction()

function(jomw_add_octave_target jomw_target_name)
  # Parse arguments
  jomw_parse_arguments(octave ${ARGN})

  # Create library target
  jomw_add_dynamic_target(${target_name} ${JOMW_NAMESPACE_PREFIX}octave "${JOMW_ADD_SOURCES}")

  # Set output name to have .oct extension
  set_target_properties(${target_name} PROPERTIES
    PREFIX ""
    SUFFIX ".oct"
    OUTPUT_NAME ${jomw_target_name})
endfunction()

function(jomw_add_target target_name)
  if(JOMW_HAS_MATHEMATICA)
    jomw_add_mathematica_target(${ARGV})
  else()
    message(STATUS "Skipping Mathematica target for ${target_name}")
  endif()

  if(JOMW_HAS_OCTAVE)
    jomw_add_octave_target(${ARGV})
  else()
    message(STATUS "Skipping Octave target for ${target_name}")
  endif()

  if(JOMW_HAS_JULIA)
    jomw_add_julia_target(${ARGV})
  else()
    message(STATUS "Skipping Julia target for ${target_name}")
  endif()
endfunction()

