#!/usr/bin/env bash
# Count-floor guard for the security negative-auth smoke subset (backlog#1151
# sec-5), built on the infra-12 mechanism (scripts/check_migration_gate_count.sh,
# backlog#1153).
#
# The e2e-smoke profile in .config/nextest.toml selects tests BY MODULE NAME.
# The three attacker-facing S3 auth-rejection suites — negative_sigv4_test
# (header SigV4, sec-1), presigned_negative_test (presigned URL, sec-2), and
# admin_auth_test (admin gate + root-credential lifecycle, sec-4) — are wired
# into that filter so they run on every PR. A rename that drops a suite out of
# the filter (or a deletion) silently thins the security gate to nothing with no
# CI signal, exactly the failure mode the migration-gate guard was built for.
#
# This script lists what the e2e-smoke profile ACTUALLY selects and counts the
# security suites among them, then fails when that number drops below the
# committed floor in .config/security-smoke-floor.txt. Because it lists via the
# profile (not a standalone name filter), it verifies real smoke MEMBERSHIP: a
# suite renamed without updating the nextest.toml filter stops being selected,
# its tests vanish from the listing, and the count falls below the floor. To
# shrink the subset intentionally, update the floor file in the same PR so the
# reduction is explicit and reviewable (adding tests never requires a bump —
# the floor is a lower bound — but bumping keeps the guard tight).
#
# NAMING CONVENTION DEPENDENCY: the security suites are matched by these
# reserved module-name prefixes:
#
#   negative_sigv4_test, presigned_negative_test, admin_auth_test
#
# Renaming a suite away from all of these prefixes removes it from the count.
# Keep this regex in sync with the module names in the e2e-smoke filter.
#
# Usage:
#   scripts/check_security_smoke_count.sh                    # count check (alias of check)
#   scripts/check_security_smoke_count.sh check              # count check only
#   scripts/check_security_smoke_count.sh check listing.json  # reuse a nextest listing

set -euo pipefail

cd "$(dirname "$0")/.."

# Anchored module-name prefixes of the security negative-auth smoke subset.
# Kept deliberately in lockstep with the e2e-smoke filter in .config/nextest.toml.
SECURITY_SMOKE_REGEX='^(negative_sigv4|presigned_negative|admin_auth)_test::'
FLOOR_FILE=".config/security-smoke-floor.txt"

mode="${1:-check}"
case "$mode" in
    all | check) ;;
    *)
        echo "usage: $0 [check]" >&2
        exit 2
        ;;
esac

if (( $# > 2 )); then
    echo "usage: $0 [check] [nextest-listing.json]" >&2
    exit 2
fi

listing_file="${2:-}"
if [[ -n "$listing_file" && ! -f "$listing_file" ]]; then
    echo "error: nextest listing does not exist: $listing_file" >&2
    exit 1
fi

floor="$(grep -Ev '^[[:space:]]*(#|$)' "$FLOOR_FILE" | head -n1 | tr -d '[:space:]')"
if ! [[ "$floor" =~ ^[0-9]+$ ]]; then
    echo "error: $FLOOR_FILE does not contain a numeric floor (got: '$floor')" >&2
    exit 1
fi

# List via the e2e-smoke PROFILE so the default-filter is applied: only the
# tests the PR smoke suite would actually run appear in the output. Count the
# ones whose test name starts with a security module prefix. CI passes the
# listing produced from the smoke archive so this guard does not rebuild the
# e2e test graph immediately before the smoke run. The structured JSON listing
# is used (not the human format) because a schema change makes jq fail loudly
# rather than silently collapsing the count to zero.
if [[ -n "$listing_file" ]]; then
    count="$(jq --arg re "$SECURITY_SMOKE_REGEX" \
        '[."rust-suites"[].testcases | to_entries[] | select(.value["filter-match"].status == "matches") | select(.key | test($re))] | length' \
        "$listing_file")"
else
    count="$(cargo nextest list --profile e2e-smoke -p e2e_test --message-format json \
        | jq --arg re "$SECURITY_SMOKE_REGEX" \
            '[."rust-suites"[].testcases | to_entries[] | select(.value["filter-match"].status == "matches") | select(.key | test($re))] | length')"
fi
if ! [[ "$count" =~ ^[0-9]+$ ]]; then
    echo "error: could not parse nextest JSON listing (got count: '$count')" >&2
    exit 1
fi

if ((count < floor)); then
    echo "error: e2e-smoke selects $count security auth-rejection tests, below the committed floor of $floor." >&2
    echo "" >&2
    echo "The security smoke subset is matched by module name (negative_sigv4_test /" >&2
    echo "presigned_negative_test / admin_auth_test) in the e2e-smoke default-filter" >&2
    echo "(.config/nextest.toml). A rename or removal has dropped one out of the smoke" >&2
    echo "suite. Either restore the module names (and this script's regex), or — if the" >&2
    echo "reduction is intentional — update $FLOOR_FILE in this PR so the" >&2
    echo "security-gate change is explicit and reviewable." >&2
    exit 1
fi
echo "security smoke count OK: $count selected auth-rejection tests (floor: $floor)"
