# auto/zstd — shared libzstd discovery for the zstd filter and static modules.
#
# Sourced exactly once from the top-level addon config before either module is
# declared, so the static/dynamic/pkg-config probe sequence lives in one place
# instead of being duplicated (and silently drifting) between filter/config and
# static/config. Exports:
#   ngx_zstd_opt_I — compiler include flags for <zstd.h>
#   ngx_zstd_opt_L — linker flags for libzstd
# and appends the link flags to NGX_LD_OPT for static nginx builds.

ngx_feature_incs="#include <zstd.h>"
# ZSTD_compressStream2() (and ZSTD_CCtx_reset(), used unconditionally by the
# module) establish a hard libzstd 1.4.0 floor. Enforce it at the feature
# probe so an older library fails configure with the not-found error below
# rather than failing the compile deep in the module sources.
ngx_feature_test="
#if ZSTD_VERSION_NUMBER < 10400
#error libzstd 1.4.0 or newer is required
#endif
(void) ZSTD_compressStream2;"
ngx_feature_libs=
ngx_feature_run=no

ngx_zstd_opt_I=
ngx_zstd_opt_L=

if [ -n "$ZSTD_INC" -o -n "$ZSTD_LIB" ]; then
    ngx_feature="ZStandard static library in $ZSTD_INC and $ZSTD_LIB"
    ngx_feature_path=$ZSTD_INC

    # we try the static shared library firstly
    ngx_zstd_opt_I="-I$ZSTD_INC -DZSTD_STATIC_LINKING_ONLY"
    ngx_zstd_opt_L="$ZSTD_LIB/libzstd.a"
    SAVED_CC_TEST_FLAGS=$CC_TEST_FLAGS
    CC_TEST_FLAGS="$ngx_zstd_opt_I $CC_TEST_FLAGS"
    SAVED_NGX_TEST_LD_OPT=$NGX_TEST_LD_OPT
    NGX_TEST_LD_OPT="$ngx_zstd_opt_L $NGX_TEST_LD_OPT"

    . auto/feature

    # restore
    CC_TEST_FLAGS=$SAVED_CC_TEST_FLAGS
    NGX_TEST_LD_OPT=$SAVED_NGX_TEST_LD_OPT

    if [ $ngx_found = no ]; then
        # then try the dynamic shared library
        ngx_feature="ZStandard dynamic library in $ZSTD_INC and $ZSTD_LIB"
        ngx_zstd_opt_L="-L$ZSTD_LIB -lzstd -Wl,-rpath,$ZSTD_LIB"

        SAVED_CC_TEST_FLAGS=$CC_TEST_FLAGS
        CC_TEST_FLAGS="$ngx_zstd_opt_I $CC_TEST_FLAGS"
        SAVED_NGX_TEST_LD_OPT=$NGX_TEST_LD_OPT
        NGX_TEST_LD_OPT="$ngx_zstd_opt_L $NGX_TEST_LD_OPT"

        . auto/feature

        # restore
        CC_TEST_FLAGS=$SAVED_CC_TEST_FLAGS
        NGX_TEST_LD_OPT=$SAVED_NGX_TEST_LD_OPT

        if [ $ngx_found = no ]; then
            cat << END
            $0: error: the ngx_http_zstd modules require the ZStandard library, please be sure that "\$ZSTD_INC" and "\$ZSTD_LIB" are set correctly.
END
            exit 1
        fi

    fi
else
    # auto-discovery: prefer dynamic linking (static libzstd.a lacks -fPIC
    # and cannot be linked into a shared .so dynamic module)
    ngx_feature="ZStandard dynamic library"
    ngx_zstd_opt_I=
    ngx_zstd_opt_L="-lzstd"

    SAVED_CC_TEST_FLAGS=$CC_TEST_FLAGS
    CC_TEST_FLAGS="$ngx_zstd_opt_I $CC_TEST_FLAGS"
    SAVED_NGX_TEST_LD_OPT=$NGX_TEST_LD_OPT
    NGX_TEST_LD_OPT="$ngx_zstd_opt_L $NGX_TEST_LD_OPT"

    . auto/feature

    # restore
    CC_TEST_FLAGS=$SAVED_CC_TEST_FLAGS
    NGX_TEST_LD_OPT=$SAVED_NGX_TEST_LD_OPT

    if [ $ngx_found = no ]; then
        # Dynamic auto-discovery failed. Try pkg-config (portable across
        # Linux, FreeBSD, OpenBSD, Gentoo, Rocky/RHEL) before giving up.
        # Note: -l:libzstd.a is GNU ld only and not used here.
        ngx_pkgconf=
        if command -v pkgconf > /dev/null 2>&1; then
            ngx_pkgconf=pkgconf
        elif command -v pkg-config > /dev/null 2>&1; then
            ngx_pkgconf=pkg-config
        fi

        if [ -n "$ngx_pkgconf" ] && $ngx_pkgconf --exists libzstd 2>/dev/null; then
            ngx_feature="ZStandard library via pkg-config"
            ngx_zstd_opt_I="$($ngx_pkgconf --cflags libzstd)"
            ngx_zstd_opt_L="$($ngx_pkgconf --libs libzstd)"

            SAVED_CC_TEST_FLAGS=$CC_TEST_FLAGS
            CC_TEST_FLAGS="$ngx_zstd_opt_I $CC_TEST_FLAGS"
            SAVED_NGX_TEST_LD_OPT=$NGX_TEST_LD_OPT
            NGX_TEST_LD_OPT="$ngx_zstd_opt_L $NGX_TEST_LD_OPT"

            . auto/feature

            # restore
            CC_TEST_FLAGS=$SAVED_CC_TEST_FLAGS
            NGX_TEST_LD_OPT=$SAVED_NGX_TEST_LD_OPT
        fi

        if [ $ngx_found = no ]; then
            cat << END
            $0: error: the ngx_http_zstd modules require the ZStandard library.
            Install libzstd-dev (Debian/Ubuntu), zstd-devel (RHEL/Rocky),
            dev-libs/zstd (Gentoo), or security/zstd (FreeBSD/OpenBSD ports),
            or set ZSTD_INC and ZSTD_LIB to the library location.
END
            exit 1
        fi
    fi

fi

NGX_LD_OPT="$ngx_zstd_opt_L $NGX_LD_OPT"

# Advisory: report the detected zstd version when a directive's full
# functionality needs a newer library than the 1.4.0 floor enforced above.
# The module always uses ZSTD_CCtx_reset() + ZSTD_compressStream2() (both
# 1.4.0); there is no ZSTD_initCStream_usingCDict() fallback path. The only
# version-gated directive is zstd_target_cblock_size (libzstd >= 1.5.6).
#
# Extract ZSTD_VERSION_NUMBER directly from the header via the
# preprocessor: feed "#include <zstd.h>" + the macro name through the
# compiler's -E and read the expanded value off the last line.
ngx_zstd_ver=$(echo "#include <zstd.h>
ZSTD_VERSION_NUMBER" | \
    $CC $ngx_zstd_opt_I -x c -E - 2>/dev/null | \
    grep -v "^#" | grep -v "^$" | tail -1 | tr -d ' ')

if [ -n "$ngx_zstd_ver" ]; then
    if [ "$ngx_zstd_ver" -lt 10506 ] 2>/dev/null; then
        cat << END
        Note: zstd version $ngx_zstd_ver detected (< 1.5.6 / 10506).
        "zstd_target_cblock_size" requires libzstd >= 1.5.6 and will have
        no effect at runtime on this build. Every other directive is
        fully functional. Upgrade libzstd to 1.5.6+ for that directive.
END
    fi
fi
