# 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``.

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

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 ()
