# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
UseSWIG
-------

Defines the following macros for use with SWIG:

.. command:: swig_add_library

  Define swig module with given name and specified language::

    swig_add_library(<name>
                     [TYPE <SHARED|MODULE|STATIC|USE_BUILD_SHARED_LIBS>]
                     LANGUAGE <language>
                     SOURCES <file>...
                     )

  The variable ``SWIG_MODULE_<name>_REAL_NAME`` will be set to the name
  of the swig module target library.

.. command:: swig_link_libraries

  Link libraries to swig module::

    swig_link_libraries(<name> [ libraries ])

Source file properties on module files can be set before the invocation
of the ``swig_add_library`` macro to specify special behavior of SWIG:

``CPLUSPLUS``
  Call SWIG in c++ mode.  For example:

  .. code-block:: cmake

    set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON)
    swig_add_library(mymod LANGUAGE python SOURCES mymod.i)

``SWIG_FLAGS``
  Add custom flags to the SWIG executable.


``SWIG_MODULE_NAME``
  Specify the actual import name of the module in the target language.
  This is required if it cannot be scanned automatically from source
  or different from the module file basename.  For example:

  .. code-block:: cmake

    set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname)

Some variables can be set to specify special behavior of SWIG:

``CMAKE_SWIG_FLAGS``
  Add flags to all swig calls.

``CMAKE_SWIG_OUTDIR``
  Specify where to write the language specific files (swig ``-outdir`` option).

``SWIG_OUTFILE_DIR``
  Specify an output directory name where the generated source file will be
  placed.  If not specified, ``CMAKE_SWIG_OUTDIR`` is used.

``SWIG_MODULE_<name>_EXTRA_DEPS``
  Specify extra dependencies for the generated module for ``<name>``.
#]=======================================================================]

set(SWIG_CXX_EXTENSION "cxx")
set(SWIG_EXTRA_LIBRARIES "")

set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py")
set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java")

#
# For given swig module initialize variables associated with it
#
macro(SWIG_MODULE_INITIALIZE name language)
  string(TOUPPER "${language}" swig_uppercase_language)
  string(TOLOWER "${language}" swig_lowercase_language)
  set(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}")
  set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}")

  set(SWIG_MODULE_${name}_REAL_NAME "${name}")
  if (";${CMAKE_SWIG_FLAGS};" MATCHES ";-noproxy;")
    set (SWIG_MODULE_${name}_NOPROXY TRUE)
  endif ()
  if("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xUNKNOWN")
    message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
  elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY)
    # swig will produce a module.py containing an 'import _modulename' statement,
    # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32),
    # unless the -noproxy flag is used
    set(SWIG_MODULE_${name}_REAL_NAME "_${name}")
  elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPERL")
    set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
  endif()
endmacro()

#
# For a given language, input file, and output file, determine extra files that
# will be generated. This is internal swig macro.
#

macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
  set(${outfiles} "")
  get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename
    ${infile} SWIG_MODULE_NAME)
  if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")

    # try to get module name from "%module foo" syntax
    if ( EXISTS ${infile} )
      file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*[a-zA-Z0-9_]+.*" )
    endif ()
    if ( _MODULE_NAME )
      string ( REGEX REPLACE "[ ]*%module[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" )
      set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}")

    else ()
      # try to get module name from "%module (options=...) foo" syntax
      if ( EXISTS ${infile} )
        file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*\\(.*\\)[ ]*[a-zA-Z0-9_]+.*" )
      endif ()
      if ( _MODULE_NAME )
        string ( REGEX REPLACE "[ ]*%module[ ]*\\(.*\\)[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" )
        set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}")

      else ()
        # fallback to file basename
        get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename ${infile} NAME_WE)
      endif ()
    endif ()

  endif()
  foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSIONS})
    set(extra_file "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}${it}")
    list(APPEND ${outfiles} ${extra_file})
    # Treat extra outputs as plain files regardless of language.
    set_property(SOURCE "${extra_file}" PROPERTY LANGUAGE "")
  endforeach()
endmacro()

#
# Take swig (*.i) file and add proper custom commands for it
#
macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
  set(swig_full_infile ${infile})
  get_filename_component(swig_source_file_name_we "${infile}" NAME_WE)
  get_source_file_property(swig_source_file_generated ${infile} GENERATED)
  get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS)
  get_source_file_property(swig_source_file_flags ${infile} SWIG_FLAGS)
  if("${swig_source_file_flags}" STREQUAL "NOTFOUND")
    set(swig_source_file_flags "")
  endif()
  get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)

  # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
  if(CMAKE_SWIG_OUTDIR)
    set(swig_outdir ${CMAKE_SWIG_OUTDIR})
  else()
    set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
  endif()

  if(SWIG_OUTFILE_DIR)
    set(swig_outfile_dir ${SWIG_OUTFILE_DIR})
  else()
    set(swig_outfile_dir ${swig_outdir})
  endif()

  if (NOT SWIG_MODULE_${name}_NOPROXY)
    SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
      swig_extra_generated_files
      "${swig_outdir}"
      "${swig_source_file_fullname}")
  endif()
  set(swig_generated_file_fullname
    "${swig_outfile_dir}/${swig_source_file_name_we}")
  # add the language into the name of the file (i.e. TCL_wrap)
  # this allows for the same .i file to be wrapped into different languages
  string(APPEND swig_generated_file_fullname
    "${SWIG_MODULE_${name}_LANGUAGE}_wrap")

  if(swig_source_file_cplusplus)
    string(APPEND swig_generated_file_fullname
      ".${SWIG_CXX_EXTENSION}")
  else()
    string(APPEND swig_generated_file_fullname
      ".c")
  endif()

  #message("Full path to source file: ${swig_source_file_fullname}")
  #message("Full path to the output file: ${swig_generated_file_fullname}")
  get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES)
  list(REMOVE_DUPLICATES cmake_include_directories)
  set(swig_include_dirs)
  foreach(it ${cmake_include_directories})
    set(swig_include_dirs ${swig_include_dirs} "-I${it}")
  endforeach()

  set(swig_special_flags)
  # default is c, so add c++ flag if it is c++
  if(swig_source_file_cplusplus)
    set(swig_special_flags ${swig_special_flags} "-c++")
  endif()
  if("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xCSHARP")
    if(NOT ";${swig_source_file_flags};${CMAKE_SWIG_FLAGS};" MATCHES ";-dllimport;")
      # This makes sure that the name used in the generated DllImport
      # matches the library name created by CMake
      set(SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport;${name}")
    endif()
  endif()
  set(swig_extra_flags)
  if(SWIG_MODULE_${name}_EXTRA_FLAGS)
    set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS})
  endif()
  # IMPLICIT_DEPENDS below can not handle situations where a dependent file is
  # removed. We need an extra step with timestamp and custom target, see #16830
  # As this is needed only for Makefile generator do it conditionally
  if(CMAKE_GENERATOR MATCHES "Make")
    get_filename_component(swig_generated_timestamp
      "${swig_generated_file_fullname}" NAME_WE)
    set(swig_gen_target gen_${name}_${swig_generated_timestamp})
    set(swig_generated_timestamp
      "${swig_outdir}/${swig_generated_timestamp}.stamp")
    set(swig_custom_output ${swig_generated_timestamp})
    set(swig_custom_products
      BYPRODUCTS "${swig_generated_file_fullname}" ${swig_extra_generated_files})
    set(swig_timestamp_command
      COMMAND ${CMAKE_COMMAND} -E touch ${swig_generated_timestamp})
  else()
    set(swig_custom_output
      "${swig_generated_file_fullname}" ${swig_extra_generated_files})
    set(swig_custom_products)
    set(swig_timestamp_command)
  endif()
  add_custom_command(
    OUTPUT ${swig_custom_output}
    ${swig_custom_products}
    # Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir)
    COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir}
    ${swig_timestamp_command}
    COMMAND "${SWIG_EXECUTABLE}"
    ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
    ${swig_source_file_flags}
    ${CMAKE_SWIG_FLAGS}
    -outdir ${swig_outdir}
    ${swig_special_flags}
    ${swig_extra_flags}
    ${swig_include_dirs}
    -o "${swig_generated_file_fullname}"
    "${swig_source_file_fullname}"
    MAIN_DEPENDENCY "${swig_source_file_fullname}"
    DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS}
    IMPLICIT_DEPENDS CXX "${swig_source_file_fullname}"
    COMMENT "Swig source")
  if(CMAKE_GENERATOR MATCHES "Make")
    add_custom_target(${swig_gen_target} DEPENDS ${swig_generated_timestamp})
  endif()
  unset(swig_generated_timestamp)
  unset(swig_custom_output)
  unset(swig_custom_products)
  unset(swig_timestamp_command)
  set_source_files_properties("${swig_generated_file_fullname}" ${swig_extra_generated_files}
    PROPERTIES GENERATED 1)
  set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files})
endmacro()

#
# Create Swig module
#
macro(SWIG_ADD_MODULE name language)
  message(DEPRECATION "SWIG_ADD_MODULE is deprecated. Use SWIG_ADD_LIBRARY instead.")
  swig_add_library(${name}
                   LANGUAGE ${language}
                   TYPE MODULE
                   SOURCES ${ARGN})
endmacro()


macro(SWIG_ADD_LIBRARY name)
  set(options "")
  set(oneValueArgs LANGUAGE
                   TYPE)
  set(multiValueArgs SOURCES)
  cmake_parse_arguments(_SAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  if(NOT DEFINED _SAM_LANGUAGE)
    message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing LANGUAGE argument")
  endif()

  if(NOT DEFINED _SAM_SOURCES)
    message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing SOURCES argument")
  endif()

  if(NOT DEFINED _SAM_TYPE)
    set(_SAM_TYPE MODULE)
  elseif("${_SAM_TYPE}" STREQUAL "USE_BUILD_SHARED_LIBS")
    unset(_SAM_TYPE)
  endif()

  swig_module_initialize(${name} ${_SAM_LANGUAGE})

  set(swig_dot_i_sources)
  set(swig_other_sources)
  foreach(it ${_SAM_SOURCES})
    if(${it} MATCHES "\\.i$")
      set(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
    else()
      set(swig_other_sources ${swig_other_sources} "${it}")
    endif()
  endforeach()

  set(swig_generated_sources)
  set(swig_generated_targets)
  foreach(it ${swig_dot_i_sources})
    SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it})
    set(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}")
    list(APPEND swig_generated_targets "${swig_gen_target}")
  endforeach()
  get_directory_property(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
  set_directory_properties(PROPERTIES
    ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}")
  add_library(${SWIG_MODULE_${name}_REAL_NAME}
    ${_SAM_TYPE}
    ${swig_generated_sources}
    ${swig_other_sources})
  if(CMAKE_GENERATOR MATCHES "Make")
    # see IMPLICIT_DEPENDS above
    add_dependencies(${SWIG_MODULE_${name}_REAL_NAME} ${swig_generated_targets})
  endif()
  if("${_SAM_TYPE}" STREQUAL "MODULE")
    set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES NO_SONAME ON)
  endif()
  string(TOLOWER "${_SAM_LANGUAGE}" swig_lowercase_language)
  if ("${swig_lowercase_language}" STREQUAL "octave")
    set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
    set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".oct")
  elseif ("${swig_lowercase_language}" STREQUAL "go")
    set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
  elseif ("${swig_lowercase_language}" STREQUAL "java")
    if (APPLE)
        # In java you want:
        #      System.loadLibrary("LIBRARY");
        # then JNI will look for a library whose name is platform dependent, namely
        #   MacOS  : libLIBRARY.jnilib
        #   Windows: LIBRARY.dll
        #   Linux  : libLIBRARY.so
        set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib")
      endif ()
  elseif ("${swig_lowercase_language}" STREQUAL "lua")
    if("${_SAM_TYPE}" STREQUAL "MODULE")
      set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
    endif()
  elseif ("${swig_lowercase_language}" STREQUAL "python")
    # this is only needed for the python case where a _modulename.so is generated
    set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
    # Python extension modules on Windows must have the extension ".pyd"
    # instead of ".dll" as of Python 2.5.  Older python versions do support
    # this suffix.
    # http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000
    # <quote>
    # Windows: .dll is no longer supported as a filename extension for extension modules.
    # .pyd is now the only filename extension that will be searched for.
    # </quote>
    if(WIN32 AND NOT CYGWIN)
      set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd")
    endif()
  elseif ("${swig_lowercase_language}" STREQUAL "r")
    set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
  elseif ("${swig_lowercase_language}" STREQUAL "ruby")
    # In ruby you want:
    #      require 'LIBRARY'
    # then ruby will look for a library whose name is platform dependent, namely
    #   MacOS  : LIBRARY.bundle
    #   Windows: LIBRARY.dll
    #   Linux  : LIBRARY.so
    set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
    if (APPLE)
      set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".bundle")
    endif ()
  elseif ("${swig_lowercase_language}" STREQUAL "perl")
    # assume empty prefix because we expect the module to be dynamically loaded
    set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
    if (APPLE)
      set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".dylib")
    endif ()
  else()
    # assume empty prefix because we expect the module to be dynamically loaded
    set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
  endif ()
endmacro()

#
# Like TARGET_LINK_LIBRARIES but for swig modules
#
macro(SWIG_LINK_LIBRARIES name)
  if(SWIG_MODULE_${name}_REAL_NAME)
    target_link_libraries(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN})
  else()
    message(SEND_ERROR "Cannot find Swig library \"${name}\".")
  endif()
endmacro()
