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

#[=======================================================================[.rst:
FindOpenSP
----------

.. versionadded:: 3.25

Try to find the OpenSP library.

Result Variables
^^^^^^^^^^^^^^^^

This will define the following variables:

``OpenSP_FOUND``
  True if (the requested version of) ``OpenSP`` is available

``OpenSP_VERSION``
  The version of ``OpenSP``

``OpenSP_VERSION_MAJOR``
  The major version of ``OpenSP``

``OpenSP_VERSION_MINOR``
  The minor version of ``OpenSP``

``OpenSP_VERSION_PATCH``
  The patch version of ``OpenSP``

``OpenSP_INCLUDE_DIRS``
  The include dirs of ``OpenSP`` with its headers

``OpenSP_LIBRARIES``
  The OpenSP library for use with target_link_libraries().
  This can be passed to target_link_libraries() instead of
  the :prop_tgt:`IMPORTED` ``OpenSP::OpenSP`` target

``OpenSP_MULTI_BYTE``
  True if ``SP_MULTI_BYTE`` was found to be defined in OpenSP's ``config.h``
  header file, which indicates that the ``OpenSP`` library was compiled with
  support for multi-byte characters. The consuming target needs to define the
  ``SP_MULTI_BYTE`` to match this value in order to avoid issues with character
  decoding.

Imported Targets
^^^^^^^^^^^^^^^^

This module defines the :prop_tgt:`IMPORTED` target ``OpenSP::OpenSP``, if
OpenSP has been found.

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

The following cache variables may also be set:

``OpenSP_INCLUDE_DIR``
  the OpenSP include directory

``OpenSP_LIBRARY``
  the absolute path of the osp library

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

cmake_policy(PUSH)
cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>

find_package(PkgConfig QUIET)
if (PkgConfig_FOUND)
  pkg_check_modules(PC_OpenSP QUIET opensp)
endif ()

if (NOT OpenSP_INCLUDE_DIR)
  find_path(OpenSP_INCLUDE_DIR
    NAMES ParserEventGeneratorKit.h
    HINTS
    ${PC_OpenSP_INCLUDEDIRS}
    ${PC_OpenSP_INCLUDE_DIRS}
    PATH_SUFFIXES OpenSP opensp
    DOC "The OpenSP include directory"
    )
endif ()

if (NOT OpenSP_LIBRARY)
  find_library(OpenSP_LIBRARY_RELEASE
    NAMES osp libosp opensp libopensp sp133 libsp
    HINTS
    ${PC_OpenSP_LIBDIR}
    ${PC_OpenSP_LIBRARY_DIRS}
    )

  find_library(OpenSP_LIBRARY_DEBUG
    NAMES ospd libospd openspd libopenspd sp133d libspd
    HINTS
    ${PC_OpenSP_LIBDIR}
    ${PC_OpenSP_LIBRARY_DIRS}
    )

  include(SelectLibraryConfigurations)
  select_library_configurations(OpenSP)
endif ()

if (OpenSP_INCLUDE_DIR)
  if (EXISTS "${OpenSP_INCLUDE_DIR}/config.h")
    if (NOT OpenSP_VERSION)
      file(STRINGS "${OpenSP_INCLUDE_DIR}/config.h" opensp_version_str REGEX "^#define[\t ]+SP_VERSION[\t ]+\".*\"")
      string(REGEX REPLACE "^.*SP_VERSION[\t ]+\"([^\"]*)\".*$" "\\1" OpenSP_VERSION "${opensp_version_str}")
      unset(opensp_version_str)
    endif ()

    if (OpenSP_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
      set(OpenSP_VERSION_MAJOR "${CMAKE_MATCH_1}")
      set(OpenSP_VERSION_MINOR "${CMAKE_MATCH_2}")
      set(OpenSP_VERSION_PATCH "${CMAKE_MATCH_3}")
    endif ()

    include(CheckCXXSymbolExists)
    check_cxx_symbol_exists(SP_MULTI_BYTE "${OpenSP_INCLUDE_DIR}/config.h" OpenSP_MULTI_BYTE)
  endif ()
endif ()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenSP
  REQUIRED_VARS OpenSP_LIBRARY OpenSP_INCLUDE_DIR
  VERSION_VAR OpenSP_VERSION
  )

mark_as_advanced(OpenSP_INCLUDE_DIR OpenSP_LIBRARY OpenSP_MULTI_BYTE)

if (OpenSP_FOUND)
  set(OpenSP_INCLUDE_DIRS ${OpenSP_INCLUDE_DIR})
  if (NOT TARGET OpenSP::OpenSP)
    add_library(OpenSP::OpenSP UNKNOWN IMPORTED)
    if (EXISTS "${OpenSP_LIBRARY}")
      set_target_properties(OpenSP::OpenSP PROPERTIES
        IMPORTED_LOCATION "${OpenSP_LIBRARY}")
    endif ()
    set_target_properties(OpenSP::OpenSP PROPERTIES
      INTERFACE_INCLUDE_DIRECTORIES "${OpenSP_INCLUDE_DIRS}")

    if (OpenSP_LIBRARY_RELEASE)
      set_target_properties(OpenSP::OpenSP PROPERTIES
        IMPORTED_LOCATION_RELEASE "${OpenSP_LIBRARY_RELEASE}")
      set_property(TARGET OpenSP::OpenSP APPEND PROPERTY
        IMPORTED_CONFIGURATIONS RELEASE)
    endif ()

    if (OpenSP_LIBRARY_DEBUG)
      set_target_properties(OpenSP::OpenSP PROPERTIES
        IMPORTED_LOCATION_DEBUG "${OpenSP_LIBRARY_DEBUG}")
      set_property(TARGET OpenSP::OpenSP APPEND PROPERTY
        IMPORTED_CONFIGURATIONS DEBUG)
    endif ()
  endif ()
endif ()

include(FeatureSummary)
set_package_properties(OpenSP PROPERTIES
  URL "http://openjade.sourceforge.net/doc/index.htm"
  DESCRIPTION "An SGML System Conforming to International Standard ISO 8879"
  )

cmake_policy(POP)
