include(CheckSymbolExists)
include(CMakePushCheckState)
include(FindPackageHandleStandardArgs)
include(SelectLibraryConfigurations)

find_path(
	LIBXML2_INCLUDE_DIR
	NAMES libxml/parser.h
	PATH_SUFFIXES libxml2
)
find_library(
	LIBXML2_LIBRARY_DEBUG
	NAMES libxml2d xml2d
)
find_library(
	LIBXML2_LIBRARY_RELEASE
	NAMES libxml2 xml2
)
select_library_configurations(LIBXML2)

if(LIBXML2_INCLUDE_DIR AND EXISTS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h")
	file(STRINGS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h" _LIBXML2_VERSION_DEFINE REGEX "[\t ]*#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\"[^\"]*\".*")
	string(REGEX REPLACE "[\t ]*#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1" LIBXML2_VERSION "${_LIBXML2_VERSION_DEFINE}")
	unset(_LIBXML2_VERSION_DEFINE)
	cmake_push_check_state(RESET)
	set(CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIR})
	check_symbol_exists(LIBXML_ICONV_ENABLED "libxml/xmlversion.h" LIBXML2_WITH_ICONV)
	check_symbol_exists(LIBXML_ICU_ENABLED "libxml/xmlversion.h" LIBXML2_WITH_ICU)
	check_symbol_exists(LIBXML_LZMA_ENABLED "libxml/xmlversion.h" LIBXML2_WITH_LZMA)
	check_symbol_exists(LIBXML_THREAD_ENABLED "libxml/xmlversion.h" LIBXML2_WITH_THREADS)
	check_symbol_exists(LIBXML_ZLIB_ENABLED "libxml/xmlversion.h" LIBXML2_WITH_ZLIB)
	cmake_pop_check_state()
endif()

unset(_LIBXML2_FIND_PACKAGE_ARGS)
set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
unset(_LIBXML2_INTERFACE_LINK_LIBRARIES)
set(LIBXML2_LIBRARIES ${LIBXML2_LIBRARY})
unset(_LIBXML2_REQUIRED_VARS)

if(LibXml2_FIND_QUIETLY)
	list(APPEND _LIBXML2_FIND_PACKAGE_ARGS QUIET)
endif()
if(LibXml2_FIND_REQUIRED)
	list(APPEND _LIBXML2_FIND_PACKAGE_ARGS REQUIRED)
endif()

if(LIBXML2_WITH_ICONV)
	find_package(Iconv ${_LIBXML2_FIND_PACKAGE_ARGS})
	list(APPEND LIBXML2_INCLUDE_DIRS ${Iconv_INCLUDE_DIRS})
	list(APPEND _LIBXML2_INTERFACE_LINK_LIBRARIES "Iconv::Iconv")
	list(APPEND LIBXML2_LIBRARIES ${Iconv_LIBRARIES})
	list(APPEND _LIBXML2_REQUIRED_VARS Iconv_FOUND)
endif()

if(LIBXML2_WITH_ICU)
	find_package(ICU ${_LIBXML2_FIND_PACKAGE_ARGS} COMPONENTS data i18n uc)
	list(APPEND _LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:ICU::data>;\$<LINK_ONLY:ICU::i18n>;\$<LINK_ONLY:ICU::uc>")
	list(APPEND LIBXML2_LIBRARIES ${ICU_LIBRARIES})
	list(APPEND _LIBXML2_REQUIRED_VARS ICU_FOUND)
endif()

if(LIBXML2_WITH_LZMA)
	find_package(LibLZMA ${_LIBXML2_FIND_PACKAGE_ARGS})
	list(APPEND _LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:LibLZMA::LibLZMA>")
	list(APPEND LIBXML2_LIBRARIES ${LIBLZMA_LIBRARIES})
	list(APPEND _LIBXML2_REQUIRED_VARS LibLZMA_FOUND)
endif()

if(LIBXML2_WITH_THREADS)
	find_package(Threads ${_LIBXML2_FIND_PACKAGE_ARGS})
	list(APPEND _LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:Threads::Threads>")
	list(APPEND LIBXML2_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
	list(APPEND _LIBXML2_REQUIRED_VARS Threads_FOUND)
endif()

if(LIBXML2_WITH_ZLIB)
	find_package(ZLIB ${_LIBXML2_FIND_PACKAGE_ARGS})
	list(APPEND _LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:ZLIB::ZLIB>")
	list(APPEND LIBXML2_LIBRARIES ${ZLIB_LIBRARIES})
	list(APPEND _LIBXML2_REQUIRED_VARS ZLIB_FOUND)
endif()

if(UNIX)
	list(APPEND _LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:m>")
	list(APPEND LIBXML2_LIBRARIES m)
endif()

if(WIN32)
	list(APPEND _LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:ws2_32>")
	list(APPEND LIBXML2_LIBRARIES ws2_32)
endif()

find_package_handle_standard_args(
	LibXml2
	FOUND_VAR LibXml2_FOUND
	REQUIRED_VARS LIBXML2_INCLUDE_DIR LIBXML2_LIBRARY ${_LIBXML2_REQUIRED_VARS}
	VERSION_VAR LIBXML2_VERSION
)

if(LibXml2_FOUND AND NOT TARGET LibXml2::LibXml2)
	add_library(LibXml2::LibXml2 UNKNOWN IMPORTED)
	if(LIBXML2_LIBRARY_RELEASE)
		set_property(TARGET LibXml2::LibXml2 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
		set_target_properties(LibXml2::LibXml2 PROPERTIES IMPORTED_LOCATION_RELEASE "${LIBXML2_LIBRARY_RELEASE}")
	endif()
	if(LIBXML2_LIBRARY_DEBUG)
		set_property(TARGET LibXml2::LibXml2 APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
		set_target_properties(LibXml2::LibXml2 PROPERTIES IMPORTED_LOCATION_DEBUG "${LIBXML2_LIBRARY_DEBUG}")
	endif()
	set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIRS}")
	set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_LINK_LIBRARIES "${_LIBXML2_INTERFACE_LINK_LIBRARIES}")
endif()

mark_as_advanced(LIBXML2_INCLUDE_DIR)
unset(_LIBXML2_FIND_PACKAGE_ARGS)
unset(_LIBXML2_INTERFACE_LINK_LIBRARIES)
unset(_LIBXML2_REQUIRED_VARS)
