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

#[=======================================================================[.rst:
FindLibLZMA
-----------

Find LZMA compression algorithm headers and library.


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

.. versionadded:: 3.14

This module defines :prop_tgt:`IMPORTED` target ``LibLZMA::LibLZMA``, if
liblzma has been found.

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

This module will set the following variables in your project:

``LIBLZMA_FOUND``
  True if liblzma headers and library were found.
``LIBLZMA_INCLUDE_DIRS``
  Directory where liblzma headers are located.
``LIBLZMA_LIBRARIES``
  Lzma libraries to link against.
``LIBLZMA_HAS_AUTO_DECODER``
  True if lzma_auto_decoder() is found (required).
``LIBLZMA_HAS_EASY_ENCODER``
  True if lzma_easy_encoder() is found (required).
``LIBLZMA_HAS_LZMA_PRESET``
  True if lzma_lzma_preset() is found (required).
``LIBLZMA_VERSION``
  .. versionadded:: 3.26
    the version of LZMA found.

  See also legacy variable ``LIBLZMA_VERSION_STRING``.

Legacy Variables
^^^^^^^^^^^^^^^^

The following variables are provided for backward compatibility:

``LIBLZMA_VERSION_MAJOR``
  The major version of lzma
``LIBLZMA_VERSION_MINOR``
  The minor version of lzma
``LIBLZMA_VERSION_PATCH``
  The patch version of lzma
``LIBLZMA_VERSION_STRING``
  version number as a string (ex: "5.0.3")

  .. versionchanged:: 3.26
    Superseded by ``LIBLZMA_VERSION``.

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

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

find_path(LIBLZMA_INCLUDE_DIR lzma.h )
if(NOT LIBLZMA_LIBRARY)
  find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma NAMES_PER_DIR PATH_SUFFIXES lib)
  find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad NAMES_PER_DIR PATH_SUFFIXES lib)
  include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
  select_library_configurations(LIBLZMA)
else()
  file(TO_CMAKE_PATH "${LIBLZMA_LIBRARY}" LIBLZMA_LIBRARY)
endif()

if(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h")
    file(STRINGS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h" LIBLZMA_HEADER_CONTENTS REGEX "#define LZMA_VERSION_[A-Z]+ [0-9]+")

    string(REGEX REPLACE ".*#define LZMA_VERSION_MAJOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MAJOR "${LIBLZMA_HEADER_CONTENTS}")
    string(REGEX REPLACE ".*#define LZMA_VERSION_MINOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MINOR "${LIBLZMA_HEADER_CONTENTS}")
    string(REGEX REPLACE ".*#define LZMA_VERSION_PATCH ([0-9]+).*" "\\1" LIBLZMA_VERSION_PATCH "${LIBLZMA_HEADER_CONTENTS}")

    set(LIBLZMA_VERSION_STRING "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}")
    set(LIBLZMA_VERSION ${LIBLZMA_VERSION_STRING})
    unset(LIBLZMA_HEADER_CONTENTS)
endif()

# We're using new code known now as XZ, even library still been called LZMA
# it can be found in http://tukaani.org/xz/
# Avoid using old codebase
if (LIBLZMA_LIBRARY)
  include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
  set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
  set(CMAKE_REQUIRED_QUIET ${LibLZMA_FIND_QUIETLY})
  if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
    set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY})
  elseif(LIBLZMA_LIBRARY_RELEASE)
    set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_RELEASE})
  elseif(LIBLZMA_LIBRARY_DEBUG)
    set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_DEBUG})
  endif()
  CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_auto_decoder "" LIBLZMA_HAS_AUTO_DECODER)
  CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_easy_encoder "" LIBLZMA_HAS_EASY_ENCODER)
  CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_lzma_preset "" LIBLZMA_HAS_LZMA_PRESET)
  unset(LIBLZMA_LIBRARY_check)
  set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
endif ()

include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(LibLZMA  REQUIRED_VARS  LIBLZMA_LIBRARY
                                                          LIBLZMA_INCLUDE_DIR
                                                          LIBLZMA_HAS_AUTO_DECODER
                                                          LIBLZMA_HAS_EASY_ENCODER
                                                          LIBLZMA_HAS_LZMA_PRESET
                                           VERSION_VAR    LIBLZMA_VERSION
                                 )
mark_as_advanced( LIBLZMA_INCLUDE_DIR LIBLZMA_LIBRARY )

if (LIBLZMA_FOUND)
    set(LIBLZMA_LIBRARIES ${LIBLZMA_LIBRARY})
    set(LIBLZMA_INCLUDE_DIRS ${LIBLZMA_INCLUDE_DIR})
    if(NOT TARGET LibLZMA::LibLZMA)
        add_library(LibLZMA::LibLZMA UNKNOWN IMPORTED)
        set_target_properties(LibLZMA::LibLZMA PROPERTIES
                              INTERFACE_INCLUDE_DIRECTORIES "${LIBLZMA_INCLUDE_DIR}"
                              IMPORTED_LINK_INTERFACE_LANGUAGES C)

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

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

        if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
            set_target_properties(LibLZMA::LibLZMA PROPERTIES
                IMPORTED_LOCATION "${LIBLZMA_LIBRARY}")
        endif()
    endif()
endif ()

cmake_policy(POP)
