#!/bin/bash
# Every tampering scenario an operator could hit must be rejected by the release
# artefacts themselves. Downloads use public curl only: gh needs git context that
# the isolated workspace removes, and the operator has neither gh nor a token.
set -euo pipefail

TAG="${1:-}"
REPOSITORY="${SMM_REPOSITORY:-ochenstarik-ui/server-monitor-manager}"

if [[ -z "$TAG" ]]; then
    echo "Usage: $0 <tag>" >&2
    exit 1
fi

BASE_URL="https://github.com/${REPOSITORY}/releases/download/${TAG}"

echo "Running negative tests against release $TAG..."

download() {
    local name="$1"
    curl --fail --silent --show-error --location --retry 3 \
        -o "$name" "${BASE_URL}/${name}" \
        || { echo "FAIL: asset is not downloadable: $name" >&2; exit 1; }
}

case "$(uname -m)" in
    x86_64) RUNTIME="linux-x64" ;;
    aarch64|arm64) RUNTIME="linux-arm64" ;;
    *) echo "FAIL: unsupported architecture $(uname -m)" >&2; exit 1 ;;
esac
ARCHIVE="server-monitor-manager-${RUNTIME}.tar.gz"

download ochenstarik-server-monitor-manager.sh
chmod +x ochenstarik-server-monitor-manager.sh
download "$ARCHIVE"
download "$ARCHIVE.sha256"
download server-monitor-manager-manifest.json
download server-monitor-manager-manifest.sig
download server-monitor-manager-manifest.pem

echo "Test 1: Altered byte in archive"
cp "$ARCHIVE" "corrupted-$ARCHIVE"
cp "$ARCHIVE.sha256" "corrupted-$ARCHIVE.sha256"
echo "corrupted" >>"corrupted-$ARCHIVE"
if ./ochenstarik-server-monitor-manager.sh verify-release "corrupted-$ARCHIVE" >/dev/null 2>&1; then
    echo "FAIL: Altered archive was accepted!" >&2
    exit 1
fi
echo "PASS: Altered archive rejected."
rm -f "corrupted-$ARCHIVE" "corrupted-$ARCHIVE.sha256"

echo "Test 2: Substituted hash in manifest without resigning"
cp server-monitor-manager-manifest.json corrupted-manifest.json
sed -i 's/"[a-f0-9]\{64\}"/"0000000000000000000000000000000000000000000000000000000000000000"/g' corrupted-manifest.json
if ./ochenstarik-server-monitor-manager.sh verify-manifest corrupted-manifest.json \
    server-monitor-manager-manifest.sig server-monitor-manager-manifest.pem >/dev/null 2>&1; then
    echo "FAIL: Manifest with substituted hash accepted!" >&2
    exit 1
fi
echo "PASS: Substituted hash rejected."
rm -f corrupted-manifest.json

echo "Test 3: Manifest without signature"
if ./ochenstarik-server-monitor-manager.sh verify-manifest server-monitor-manager-manifest.json \
    "" server-monitor-manager-manifest.pem >/dev/null 2>&1; then
    echo "FAIL: Manifest without signature accepted!" >&2
    exit 1
fi
echo "PASS: Missing signature rejected."

echo "Test 4: Signature made by another identity"
export COSIGN_PASSWORD=""
cosign generate-key-pair >/dev/null
cosign sign-blob --yes --key cosign.key \
    --use-signing-config=false --new-bundle-format=false \
    --output-signature fake.sig server-monitor-manager-manifest.json >/dev/null
if ./ochenstarik-server-monitor-manager.sh verify-manifest server-monitor-manager-manifest.json \
    fake.sig server-monitor-manager-manifest.pem >/dev/null 2>&1; then
    echo "FAIL: Signature from wrong identity accepted!" >&2
    exit 1
fi
echo "PASS: Wrong identity signature rejected."
rm -f cosign.key cosign.pub fake.sig

echo "Test 5: Missing certificate beside the archive"
mkdir -p no-cert && cp "$ARCHIVE" "$ARCHIVE.sha256" \
    server-monitor-manager-manifest.json server-monitor-manager-manifest.sig no-cert/
if ./ochenstarik-server-monitor-manager.sh verify-release "no-cert/$ARCHIVE" >/dev/null 2>&1; then
    echo "FAIL: Archive accepted without the signing certificate!" >&2
    exit 1
fi
echo "PASS: Missing certificate rejected."
rm -rf no-cert

echo "All negative tests passed!"
