macro (pkg_convert_to_static prefix module)
    if (${prefix}_FOUND)
        set (${prefix}_LDFLAGS "")
        execute_process (
            COMMAND ${PKG_CONFIG_EXECUTABLE} --libs --static ${module}
            OUTPUT_VARIABLE searchLibs
            OUTPUT_STRIP_TRAILING_WHITESPACE
        )
        string (REPLACE "-l" "" searchLibs ${searchLibs})
        string (REPLACE " " ";" searchLibs ${searchLibs})
        foreach (name ${searchLibs})
            if (name STREQUAL "dl")
                list (APPEND ${prefix}_LDFLAGS -ldl)
            elseif (name STREQUAL "-pthread")
                list (APPEND ${prefix}_LDFLAGS ${name})
            else ()
                set (fname ${name}.a)
                set (_added NO)
                foreach (libpath ${${prefix}_LIBRARY_DIRS})
                    if (NOT _added)
                        set (_name ${libpath}/lib${fname})
                        if (EXISTS ${_name})
                            list (APPEND ${prefix}_LDFLAGS ${_name})
                            set (_added YES)
                        endif ()
                    endif ()
                endforeach ()
                if (NOT _added)
                    list (APPEND ${prefix}_LDFLAGS ${name}.a)
                endif ()
            endif ()
        endforeach ()
        set (name)
        list (REMOVE_DUPLICATES ${${prefix}}_LDFLAGS)
        set (${prefix}_LIBRARIES ${${prefix}_LDFLAGS})
        message (STATUS "Staticified ${prefix}_LDFLAGS: ${${prefix}_LDFLAGS}")
    endif ()
endmacro ()


# Dependencies for the_Foundation
if (NOT IOS AND NOT ANDROID)
    # Regular desktop environmment.
    if (VCPKG_TOOLCHAIN)
        # Use find_package for vcpkg-managed dependencies.
        find_package (ZLIB QUIET)
        find_package (pcre2 CONFIG QUIET)
        if (pcre2_FOUND)
            set (PCRE2_FOUND YES)
        endif ()
        if (TFDN_ENABLE_WEBREQUEST)
            find_package (CURL CONFIG QUIET)
        else ()
            set (CURL_FOUND NO)
            set (iHaveCurl NO)
        endif ()
        if (TFDN_ENABLE_TLSREQUEST)
            find_package (OpenSSL QUIET)
        else ()
            set (OPENSSL_FOUND NO)
            set (iHaveOpenSSL NO)
        endif ()
        # libunistring + iconv: located automatically via vcpkg's CMAKE_PREFIX_PATH
        find_path (UNISTRING_INCLUDE_DIR unistr.h)
        find_library (UNISTRING_LIB unistring)
        if (NOT UNISTRING_INCLUDE_DIR OR NOT UNISTRING_LIB)
            message (FATAL_ERROR "libunistring not found (install via vcpkg: libunistring)")
        endif ()
        find_package (Iconv REQUIRED)
        set (UNISTRING_INCLUDE_DIRS ${UNISTRING_INCLUDE_DIR})
        set (UNISTRING_LIBRARIES ${UNISTRING_LIB})
    else ()
        # Something POSIX: find dependencies using pkg-config.
        find_package (PkgConfig)
        pkg_check_modules (ZLIB zlib)
        pkg_check_modules (PCRE libpcre)     # Regular expressions
        pkg_check_modules (PCRE2 libpcre2-8) # this is preferred, if found
        if (TFDN_ENABLE_WEBREQUEST)
            pkg_check_modules (CURL libcurl)
        else ()
            set (CURL_FOUND NO)
            set (iHaveCurl NO)
        endif ()
        if (TFDN_ENABLE_TLSREQUEST)
            set (OPENSSL_FOUND NO)
            set (iHaveOpenSSL NO)
            if (FREEBSD)
                # Try the system-provided libraries first.
                find_library (LIBSSL ssl)
                find_library (LIBCRYPTO crypto)
                if (LIBSSL AND LIBCRYPTO)
                   message (STATUS "Using system-provided libssl: ${LIBSSL}")
                    add_library (libssl INTERFACE)
                    target_link_libraries (libssl INTERFACE ${LIBSSL} ${LIBCRYPTO})
                    set (OPENSSL_FOUND YES)
                else ()
                    pkg_check_modules (OPENSSL eopenssl11)
                    if (OPENSSL_FOUND)
                        set (EOPENSSL_FOUND YES)
                    endif ()
                endif ()
            else ()
                 pkg_check_modules (OPENSSL openssl)
            endif ()
        endif ()

        # Unicode text strings
        set (UNISTRING_DIR "" CACHE PATH "Location of libunistring")
        set (UNISTRING_ICONV YES CACHE BOOL "Is libunistring linked to iconv?")
        if (UNISTRING_DIR STREQUAL "")
            find_file (UNISTR_H unistr.h PATHS /usr/local/include /opt/homebrew/include)
            if (NOT UNISTR_H)
                message (FATAL_ERROR "Not found: unistr.h from GNU libunistring (set UNISTRING_DIR)")
            endif ()
            get_filename_component (UNISTRING_DIR ${UNISTR_H} PATH)
            get_filename_component (UNISTRING_DIR ${UNISTRING_DIR} PATH)
            if (NOT EXISTS ${UNISTRING_DIR}/lib/libunistring.a)
                find_library (UNISTRING_STATIC libunistring.a)
                get_filename_component (UNISTRING_LIBDIR ${UNISTRING_STATIC} PATH)
            else ()
                set (UNISTRING_LIBDIR ${UNISTRING_DIR}/lib)
            endif ()
        else ()
            set (UNISTRING_LIBDIR ${UNISTRING_DIR}/lib)
        endif ()
        set (UNISTRING_LIBRARY_DIRS ${UNISTRING_LIBDIR})
        if (UNISTRING_DIR STREQUAL "/usr")
            # Default system library.
            set (UNISTRING_LIBRARIES unistring)
        else ()
            set (UNISTRING_INCLUDE_DIRS ${UNISTRING_DIR}/include)
            set (UNISTRING_LIBRARIES -L${UNISTRING_LIBDIR} unistring)
        endif ()

        if (MINGW)
            # Switch to static linking of the dependencies to avoid distributing
            # runtime DLLs on Windows.
            set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPCRE2_STATIC -DIN_LIBUNISTRING -DIDN2_STATIC -DPSL_STATIC")
            set (PCRE2_LIBRARIES pcre2-8.a)
            set (ZLIB_LIBRARIES z.a)
            set (UNISTRING_LIBRARIES unistring.a iconv.a)
        endif ()

        if (TFDN_ENABLE_STATIC_LINK)
            message (STATUS "Static dependency linking enabled")
            # TODO: There are probably better ways to find the static linking libraries?
            # Try if `pkg-config --static` gives anything?
            set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPCRE2_STATIC -DIN_LIBUNISTRING -DIDN2_STATIC -DPSL_STATIC")
            pkg_convert_to_static (PCRE2 libpcre2-8)
            pkg_convert_to_static (PCRE libpcre)
            pkg_convert_to_static (ZLIB zlib)
            set (UNISTRING_LIBRARIES ${UNISTRING_LIBDIR}/libunistring.a)
            if (UNISTRING_ICONV)
                list (APPEND UNISTRING_LIBRARIES ${UNISTRING_LIBDIR}/libiconv.a)
            endif ()
            if (APPLE)
                list (APPEND UNISTRING_LIBRARIES "-framework CoreFoundation")
            endif ()
            if (TFDN_ENABLE_TLSREQUEST)
                pkg_convert_to_static (OPENSSL openssl)
            endif ()
        endif ()
    endif ()
elseif (IOS)
    if (IOS_DIR STREQUAL "")
        message (FATAL_ERROR "iOS dependencies not found (set IOS_DIR)")
    endif ()
    set (ZLIB_FOUND YES)
    set (ZLIB_LIBRARIES z)
    set (PCRE_FOUND YES)
    set (PCRE_LIBRARIES ${IOS_DIR}/lib/libpcre.a)
    set (PCRE_INCLUDE_DIRS ${IOS_DIR}/include)
    if (TFDN_ENABLE_WEBREQUEST)
        set (CURL_FOUND YES)
        set (CURL_LIBRARIES ${IOS_DIR}/lib/libcurl.a "-framework CoreFoundation" "-framework Security")
        set (CURL_INCLUDE_DIRS ${IOS_DIR}/include)
    else ()
        set (CURL_FOUND NO)
    endif ()
    if (TFDN_ENABLE_TLSREQUEST)
        set (OPENSSL_FOUND YES)
        set (OPENSSL_INCLUDE_DIRS ${IOS_DIR}/include)
        set (OPENSSL_LDFLAGS ${IOS_DIR}/lib/libssl.a;${IOS_DIR}/lib/libcrypto.a)
    else ()
        set (OPENSSL_FOUND NO)
    endif ()
    set (UNISTRING_INCLUDE_DIRS ${IOS_DIR}/include)
    set (UNISTRING_LIBRARIES ${IOS_DIR}/lib/libunistring.a;${IOS_DIR}/lib/libiconv.a)
elseif (ANDROID)
    if (ANDROID_DIR STREQUAL "")
        message (FATAL_ERROR "Android dependencies not found (set ANDROID_DIR)")
    endif ()
    set (ZLIB_FOUND YES)
    set (ZLIB_LIBRARIES z log)
    set (PCRE_FOUND YES)
    set (PCRE_INCLUDE_DIRS ${ANDROID_DIR}/libpcre-android/${ANDROID_ABI}/include)
    set (PCRE_LIBRARIES ${ANDROID_DIR}/libpcre-android/${ANDROID_ABI}/lib/libpcre.a)
    if (TFDN_ENABLE_TLSREQUEST)
        set (OPENSSL_FOUND YES)
        set (OPENSSL_INCLUDE_DIRS ${ANDROID_DIR}/openssl-android/${ANDROID_ABI}/include)
        set (OPENSSL_LDFLAGS ${ANDROID_DIR}/openssl-android/${ANDROID_ABI}/lib/libssl.a;${ANDROID_DIR}/openssl-android/${ANDROID_ABI}/lib/libcrypto.a)
    else ()
        set (OPENSSL_FOUND NO)
    endif ()
    set (UNISTRING_INCLUDE_DIRS ${ANDROID_DIR}/libunistring-android/${ANDROID_ABI}/include)
    set (UNISTRING_LIBRARIES ${ANDROID_DIR}/libunistring-android/${ANDROID_ABI}/lib/libunistring.a;${ANDROID_DIR}/libiconv-android/${ANDROID_ABI}/lib/libiconv.so)
endif ()

if (ZLIB_FOUND)
    set (iHaveZlib YES)
endif ()
if (PCRE_FOUND)
    set (iHavePcre YES)
endif ()
if (PCRE2_FOUND)
    set (iHavePcre2 YES)
endif ()
if (CURL_FOUND)
    set (iHaveCurl YES)
endif ()
if (OPENSSL_FOUND)
    set (iHaveOpenSSL YES)
endif ()

macro (tfdn_link_depends target mode)
    target_include_directories (${target} ${mode}
        ${UNISTRING_INCLUDE_DIRS}
        ${ZLIB_INCLUDE_DIRS}
        ${PCRE_INCLUDE_DIRS}
        ${CURL_INCLUDE_DIRS}
        ${OPENSSL_INCLUDE_DIRS}
    )
    target_link_libraries (${target} ${mode} ${UNISTRING_LIBRARIES})
    if (iPlatformWindows)
        target_link_libraries (${target} ${mode} ws2_32 iphlpapi)   # Winsock2
    endif ()

    if (VCPKG_TOOLCHAIN)
        # Link against the imported targets set up during detection.
        target_link_libraries (${target} ${mode} ZLIB::ZLIB)
        target_link_libraries (${target} ${mode} PCRE2::8BIT PCRE2::16BIT PCRE2::32BIT PCRE2::POSIX)
        target_link_libraries (${target} ${mode} Iconv::Iconv)
        if (CURL_FOUND)
            target_link_libraries (${target} ${mode} CURL::libcurl)
        endif ()
        if (iHaveTlsRequest AND OPENSSL_FOUND)
            target_link_libraries (${target} ${mode} OpenSSL::SSL OpenSSL::Crypto)
        endif ()
    else ()
        if (ZLIB_FOUND)
            target_link_libraries (${target} ${mode} ${ZLIB_LIBRARIES})
        endif ()
        if (PCRE2_FOUND)
            target_link_libraries (${target} ${mode} ${PCRE2_LIBRARIES})
        elseif (PCRE_FOUND)
            target_link_libraries (${target} ${mode} ${PCRE_LIBRARIES})
        endif ()
        if (CURL_FOUND)
            target_link_libraries (${target} ${mode} ${CURL_LIBRARIES})
        endif ()
        if (iHaveTlsRequest AND OPENSSL_FOUND)
            if (TARGET libssl AND NOT TFDN_ENABLE_STATIC_LINK)
                target_link_libraries (${target} ${mode} libssl)
            else ()
                target_link_libraries (${target} ${mode} ${OPENSSL_LDFLAGS})
            endif ()
        endif ()
    endif ()
endmacro ()
