#!/usr/bin/env bash
# Corpus-only fuzz regression: runs each fuzz target against its seed corpus
# with -runs=0 (no new mutations). Validates that:
# 1. All corpus files parse without panicking
# 2. No regressions in error handling
# 3. The fuzz harness builds and links correctly
#
# Covers both core (soliton) and CAPI (soliton_capi) fuzz targets.
#
# Usage: ./ci_regression.sh
# Exit code: 0 if all pass, non-zero on first failure.

set -euo pipefail

CORE_DIR="soliton"
CAPI_DIR="soliton_capi"

CORE_TARGETS=(
    fuzz_storage_decrypt_blob
    fuzz_ratchet_decrypt
    fuzz_ratchet_decrypt_stateful
    fuzz_ratchet_encrypt
    fuzz_identity_from_bytes
    fuzz_ed25519_verify
    fuzz_hybrid_verify
    fuzz_decrypt_first_message
    fuzz_kex_receive_session
    fuzz_storage_encrypt_blob
    fuzz_auth_respond
    fuzz_kex_verify_bundle
    fuzz_verification_phrase
    fuzz_ratchet_roundtrip
    fuzz_xwing_roundtrip
    fuzz_identity_sign_verify
    fuzz_session_init_roundtrip
    fuzz_call_derive
    fuzz_auth_verify
    fuzz_ratchet_from_bytes_epoch
    fuzz_kex_decode_receive
    fuzz_dm_queue_roundtrip
    fuzz_dm_queue_decrypt_blob
    fuzz_argon2_params
    fuzz_stream_decrypt
    fuzz_stream_decrypt_at
    fuzz_stream_encrypt_decrypt
    fuzz_stream_encrypt_at
    fuzz_ratchet_state_machine
)

CAPI_TARGETS=(
    fuzz_capi_ratchet_from_bytes
    fuzz_capi_storage_decrypt
    fuzz_capi_decode_session_init
    fuzz_capi_dm_queue_decrypt
    fuzz_capi_stream_decrypt
    fuzz_capi_stream_decrypt_at
    fuzz_capi_stream_encrypt_at
)

run_regression() {
    local fuzz_dir="$1"
    local label="$2"
    shift 2
    local targets=("$@")

    echo ""
    echo "=== ${label} (${#targets[@]} targets) ==="

    for target in "${targets[@]}"; do
        corpus_dir="${fuzz_dir}/fuzz/corpus/${target}"
        if [ ! -d "$corpus_dir" ] || [ -z "$(ls -A "$corpus_dir" 2>/dev/null)" ]; then
            echo "WARNING: No corpus for ${target}, skipping"
            continue
        fi

        echo "--- ${target} ---"
        (cd "$fuzz_dir" && cargo +nightly fuzz run "${target}" "fuzz/corpus/${target}" -- -runs=0 -max_len=65536)
        echo "PASS: ${target}"
    done
}

run_regression "$CORE_DIR" "Core" "${CORE_TARGETS[@]}"
run_regression "$CAPI_DIR" "CAPI" "${CAPI_TARGETS[@]}"

TOTAL=$(( ${#CORE_TARGETS[@]} + ${#CAPI_TARGETS[@]} ))
echo ""
echo "All ${TOTAL} corpus regressions passed."
