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

#[=======================================================================[.rst:
FindODBC
--------

Find an Open Database Connectivity (ODBC) include directory and library.

On Windows, when building with Visual Studio, this module assumes the ODBC
library is provided by the available Windows SDK.

On Unix, this module allows to search for ODBC library provided by
unixODBC or iODBC implementations of ODBC API.
This module reads hint about location of the config program:

.. variable:: ODBC_CONFIG

  Location of odbc_config or iodbc-config program

Otherwise, this module tries to find the config program,
first from unixODBC, then from iODBC.
If no config program found, this module searches for ODBC header
and library in list of known locations.

Imported targets
^^^^^^^^^^^^^^^^

This module defines the following :prop_tgt:`IMPORTED` targets:

.. variable:: ODBC::ODBC

  Imported target for using the ODBC library, if found.

Result variables
^^^^^^^^^^^^^^^^

.. variable:: ODBC_FOUND

  Set to true if ODBC library found, otherwise false or undefined.

.. variable:: ODBC_INCLUDE_DIRS

  Paths to include directories listed in one variable for use by ODBC client.
  May be empty on Windows, where the include directory corresponding to the
  expected Windows SDK is already available in the compilation environment.

.. variable:: ODBC_LIBRARIES

  Paths to libraries to linked against to use ODBC.
  May just a library name on Windows, where the library directory corresponding
  to the expected Windows SDK is already available in the compilation environment.

.. variable:: ODBC_CONFIG

  Path to unixODBC or iODBC config program, if found or specified.

Cache variables
^^^^^^^^^^^^^^^

For users who wish to edit and control the module behavior, this module
reads hints about search locations from the following variables:

.. variable:: ODBC_INCLUDE_DIR

  Path to ODBC include directory with ``sql.h`` header.

.. variable:: ODBC_LIBRARY

  Path to ODBC library to be linked.

These variables should not be used directly by project code.

Limitations
^^^^^^^^^^^

On Windows, this module does not search for iODBC.
On Unix, there is no way to prefer unixODBC over iODBC, or vice versa,
other than providing the config program location using the ``ODBC_CONFIG``.
This module does not allow to search for a specific ODBC driver.

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

# Define lists used internally
set(_odbc_include_paths)
set(_odbc_lib_paths)
set(_odbc_lib_names)
set(_odbc_required_libs_names)

### Try Windows Kits ##########################################################
if(WIN32)
  # List names of ODBC libraries on Windows
  set(ODBC_LIBRARY odbc32.lib)
  set(_odbc_lib_names odbc32;)

  # List additional libraries required to use ODBC library
  if(MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
    set(_odbc_required_libs_names odbccp32;ws2_32)
  elseif(MINGW)
    set(_odbc_required_libs_names odbccp32)
  endif()
endif()

### Try unixODBC or iODBC config program ######################################
if (UNIX)
  find_program(ODBC_CONFIG
    NAMES odbc_config iodbc-config
    DOC "Path to unixODBC or iODBC config program")
  mark_as_advanced(ODBC_CONFIG)
endif()

if (UNIX AND ODBC_CONFIG)
  # unixODBC and iODBC accept unified command line options
  execute_process(COMMAND ${ODBC_CONFIG} --cflags
    OUTPUT_VARIABLE _cflags OUTPUT_STRIP_TRAILING_WHITESPACE)
  execute_process(COMMAND ${ODBC_CONFIG} --libs
    OUTPUT_VARIABLE _libs OUTPUT_STRIP_TRAILING_WHITESPACE)

  # Collect paths of include directories from CFLAGS
  separate_arguments(_cflags NATIVE_COMMAND "${_cflags}")
  foreach(arg IN LISTS _cflags)
    if("${arg}" MATCHES "^-I(.*)$")
      list(APPEND _odbc_include_paths "${CMAKE_MATCH_1}")
    endif()
  endforeach()
  unset(_cflags)

  # Collect paths of library names and directories from LIBS
  separate_arguments(_libs NATIVE_COMMAND "${_libs}")
  foreach(arg IN LISTS _libs)
    if("${arg}" MATCHES "^-L(.*)$")
      list(APPEND _odbc_lib_paths "${CMAKE_MATCH_1}")
    elseif("${arg}" MATCHES "^-l(.*)$")
      set(_lib_name ${CMAKE_MATCH_1})
      string(REGEX MATCH "odbc" _is_odbc ${_lib_name})
      if(_is_odbc)
        list(APPEND _odbc_lib_names ${_lib_name})
      else()
        list(APPEND _odbc_required_libs_names ${_lib_name})
      endif()
      unset(_lib_name)
    endif()
  endforeach()
  unset(_libs)
endif()

### Try unixODBC or iODBC in include/lib filesystems ##########################
if (UNIX AND NOT ODBC_CONFIG)
  # List names of both ODBC libraries, unixODBC and iODBC
  set(_odbc_lib_names odbc;iodbc;unixodbc;)
endif()

### Find include directories ##################################################
find_path(ODBC_INCLUDE_DIR
  NAMES sql.h
  PATHS ${_odbc_include_paths})

if(NOT ODBC_INCLUDE_DIR AND WIN32)
  set(ODBC_INCLUDE_DIR "")
endif()

### Find libraries ############################################################
if(NOT ODBC_LIBRARY)
  find_library(ODBC_LIBRARY
    NAMES ${_odbc_lib_names}
    PATHS ${_odbc_lib_paths}
    PATH_SUFFIXES odbc)

  foreach(_lib IN LISTS _odbc_required_libs_names)
    find_library(_lib_path
      NAMES ${_lib}
      PATHS ${_odbc_lib_paths} # system parths or collected from ODBC_CONFIG
      PATH_SUFFIXES odbc)
    if(_lib_path)
      list(APPEND _odbc_required_libs_paths ${_lib_path})
    endif()
    unset(_lib_path CACHE)
  endforeach()
endif()

# Unset internal lists as no longer used
unset(_odbc_include_paths)
unset(_odbc_lib_paths)
unset(_odbc_lib_names)
unset(_odbc_required_libs_names)

### Set result variables ######################################################
set(_odbc_required_vars ODBC_LIBRARY)
if(NOT WIN32)
  list(APPEND _odbc_required_vars ODBC_INCLUDE_DIR)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ODBC DEFAULT_MSG ${_odbc_required_vars})

unset(_odbc_required_vars)

mark_as_advanced(ODBC_LIBRARY ODBC_INCLUDE_DIR)

set(ODBC_INCLUDE_DIRS ${ODBC_INCLUDE_DIR})
list(APPEND ODBC_LIBRARIES ${ODBC_LIBRARY})
list(APPEND ODBC_LIBRARIES ${_odbc_required_libs_paths})

### Import targets ############################################################
if(ODBC_FOUND)
  if(NOT TARGET ODBC::ODBC)
    if(IS_ABSOLUTE "${ODBC_LIBRARY}")
      add_library(ODBC::ODBC UNKNOWN IMPORTED)
      set_target_properties(ODBC::ODBC PROPERTIES
        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
        IMPORTED_LOCATION "${ODBC_LIBRARY}")
    else()
      add_library(ODBC::ODBC INTERFACE IMPORTED)
      set_target_properties(ODBC::ODBC PROPERTIES
        IMPORTED_LIBNAME "${ODBC_LIBRARY}")
    endif()
    set_target_properties(ODBC::ODBC PROPERTIES
      INTERFACE_INCLUDE_DIRECTORIES "${ODBC_INCLUDE_DIR}")

    if(_odbc_required_libs_paths)
      set_property(TARGET ODBC::ODBC APPEND PROPERTY
        INTERFACE_LINK_LIBRARIES "${_odbc_required_libs_paths}")
    endif()
  endif()
endif()

unset(_odbc_required_libs_paths)
