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

#[=======================================================================[.rst:
FindSWIG
--------

Find the Simplified Wrapper and Interface Generator (SWIG_) executable.

This module finds an installed SWIG and determines its version.

.. versionadded:: 3.18
  If a ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` argument is given to the
  :command:`find_package` command, it will also determine supported target
  languages.

.. versionadded:: 3.19
  When a version is requested, it can be specified as a simple value or as a
  range. For a detailed description of version range usage and capabilities,
  refer to the :command:`find_package` command.

The module defines the following variables:

``SWIG_FOUND``
  Whether SWIG and any required components were found on the system.
``SWIG_EXECUTABLE``
  Path to the SWIG executable.
``SWIG_DIR``
  Path to the installed SWIG ``Lib`` directory (result of ``swig -swiglib``).
``SWIG_VERSION``
  SWIG executable version (result of ``swig -version``).
``SWIG_<lang>_FOUND``
  If ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` are requested, each available
  target language ``<lang>`` (lowercase) will be set to TRUE.

Any ``COMPONENTS`` given to ``find_package`` should be the names of supported
target languages as provided to the LANGUAGE argument of ``swig_add_library``,
such as ``python`` or ``perl5``. Language names *must* be lowercase.

All information is collected from the ``SWIG_EXECUTABLE``, so the version
to be found can be changed from the command line by means of setting
``SWIG_EXECUTABLE``.

Example usage requiring SWIG 4.0 or higher and Python language support, with
optional Fortran support:

.. code-block:: cmake

   find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS fortran)
   if(SWIG_FOUND)
     message("SWIG found: ${SWIG_EXECUTABLE}")
     if(NOT SWIG_fortran_FOUND)
       message(WARNING "SWIG Fortran bindings cannot be generated")
     endif()
   endif()

.. _SWIG: https://swig.org

#]=======================================================================]

include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)

function(_swig_get_version _swig_executable _swig_version)
  unset(${_swig_version} PARENT_SCOPE)
  # Determine SWIG version
  execute_process(COMMAND "${_swig_executable}" -version
    OUTPUT_VARIABLE _swig_output
    ERROR_VARIABLE _swig_output
    RESULT_VARIABLE _swig_result)
  if(_swig_result)
    set_property (CACHE _SWIG_REASON_FAILURE PROPERTY VALUE "Cannot use the executable \"${_swig_executable}\"")
    if (_swig_output)
      set_property (CACHE _SWIG_REASON_FAILURE APPEND_STRING PROPERTY VALUE ": ${_swig_output}")
    endif()
  else()
    string(REGEX REPLACE ".*SWIG Version[^0-9.]*\([0-9.]+\).*" "\\1"
                         _swig_output "${_swig_output}")
    set(${_swig_version} ${_swig_output} PARENT_SCOPE)
  endif()
endfunction()

function(_swig_validate_find_executable status executable)
  _swig_get_version("${executable}" _swig_find_version)
  if(NOT _swig_find_version)
    # executable is unusable
    set (${status} FALSE PARENT_SCOPE)
    return()
  endif()
  if(NOT SWIG_FIND_VERSION)
    return()
  endif()

  find_package_check_version(${_swig_find_version}  _swig_version_is_valid HANDLE_VERSION_RANGE)
  if(_swig_version_is_valid)
    unset(_SWIG_REASON_FAILURE CACHE)
  else()
    set (${status} FALSE PARENT_SCOPE)
    set_property (CACHE _SWIG_REASON_FAILURE PROPERTY VALUE "Could NOT find SWIG: Found unsuitable version \"${_swig_find_version}\" for the executable \"${executable}\"")
  endif()
endfunction()

unset (_SWIG_REASON_FAILURE)
set (_SWIG_REASON_FAILURE CACHE INTERNAL "SWIG reason failure")

# compute list of possible names
unset (_SWIG_NAMES)
if (SWIG_FIND_VERSION_RANGE)
  foreach (_SWIG_MAJOR IN ITEMS 4 3 2)
    if (_SWIG_MAJOR VERSION_GREATER_EQUAL SWIG_FIND_VERSION_MIN_MAJOR
        AND ((SWIG_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND _SWIG_MAJOR VERSION_LESS_EQUAL SWIG_FIND_VERSION_MAX)
        OR (SWIG_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND _SWIG_MAJOR VERSION_LESS SWIG_FIND_VERSION_MAX)))
      list (APPEND _SWIG_NAMES swig${_SWIG_MAJOR}.0)
    endif()
  endforeach()
elseif(SWIG_FIND_VERSION)
  if (SWIG_FIND_VERSION_EXACT)
    set(_SWIG_NAMES swig${SWIG_FIND_VERSION_MAJOR}.0)
  else()
    foreach (_SWIG_MAJOR IN ITEMS 4 3 2)
      if (_SWIG_MAJOR VERSION_GREATER_EQUAL SWIG_FIND_VERSION_MAJOR)
        list (APPEND _SWIG_NAMES swig${_SWIG_MAJOR}.0)
      endif()
    endforeach()
  endif()
else()
  set (_SWIG_NAMES swig4.0 swig3.0 swig2.0)
endif()
if (NOT _SWIG_NAMES)
  # try to find any version
  set (_SWIG_NAMES swig4.0 swig3.0 swig2.0)
endif()

find_program(SWIG_EXECUTABLE NAMES ${_SWIG_NAMES} swig NAMES_PER_DIR
                             VALIDATOR _swig_validate_find_executable)
unset(_SWIG_NAMES)

if(SWIG_EXECUTABLE AND NOT SWIG_DIR)
  # Find default value for SWIG library directory
  execute_process(COMMAND "${SWIG_EXECUTABLE}" -swiglib
    OUTPUT_VARIABLE _swig_output
    ERROR_VARIABLE _swig_error
    RESULT_VARIABLE _swig_result)

  if(_swig_result)
    set(_msg "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${_swig_error}")
    if(SWIG_FIND_REQUIRED)
      message(SEND_ERROR "${_msg}")
    else()
      message(STATUS "${_msg}")
    endif()
    unset(_msg)
  else()
    string(REGEX REPLACE "[\n\r]+" ";" _SWIG_LIB ${_swig_output})
  endif()

  # Find SWIG library directory
  find_path(SWIG_DIR swig.swg PATHS ${_SWIG_LIB} NO_CMAKE_FIND_ROOT_PATH)
  unset(_SWIG_LIB)
endif()

if(SWIG_EXECUTABLE AND SWIG_DIR AND NOT SWIG_VERSION)
  # Determine SWIG version
  _swig_get_version("${SWIG_EXECUTABLE}" _swig_output)
  set(SWIG_VERSION ${_swig_output} CACHE STRING "Swig version" FORCE)
endif()

if(SWIG_EXECUTABLE AND SWIG_FIND_COMPONENTS)
  execute_process(COMMAND "${SWIG_EXECUTABLE}" -help
    OUTPUT_VARIABLE _swig_output
    ERROR_VARIABLE _swig_error
    RESULT_VARIABLE _swig_result)
  if(_swig_result)
    message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -help\" failed with output:\n${_swig_error}")
  else()
    string(REPLACE "\n" ";" _swig_output "${_swig_output}")
    foreach(SWIG_line IN LISTS _swig_output)
      if(SWIG_line MATCHES "-([A-Za-z0-9_]+) +- *Generate.*wrappers")
        set(SWIG_${CMAKE_MATCH_1}_FOUND TRUE)
      endif()
    endforeach()
  endif()
endif()

find_package_handle_standard_args(
  SWIG HANDLE_COMPONENTS
  REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
  VERSION_VAR SWIG_VERSION
  HANDLE_VERSION_RANGE
  FAIL_MESSAGE "${_SWIG_REASON_FAILURE}")

unset(_swig_output)
unset(_swig_error)
unset(_swig_result)

unset(_SWIG_REASON_FAILURE CACHE)

if(SWIG_FOUND)
  set(SWIG_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/UseSWIG.cmake")
endif()

mark_as_advanced(SWIG_DIR SWIG_VERSION SWIG_EXECUTABLE)
