#!/bin/bash

MAX_RETRIES=10
RETRY_DELAY=1 # seconds between retries

get-x509-authorities-count() {
    local server=$1
    docker compose exec -T $server /opt/spire/bin/spire-server bundle show -output json | jq '.x509_authorities | length'
}

old_authority=$(docker compose exec -T root-server \
    /opt/spire/bin/spire-server localauthority x509 show -output json | jq .old.authority_id -r) || fail-now "Failed to get old authority"

log-debug "Old authority: $old_authority"

x509_authorities_count=$(get-x509-authorities-count root-server)

if [ $x509_authorities_count -eq 2 ]; then
    log-debug "Two X.509 Authorities found"
else
    fail-now "Expected to be two X.509 Authorities. Found $x509_authorities_count."
fi

tainted_found=$(docker compose exec -T root-server /opt/spire/bin/spire-server bundle show -output json | jq '.x509_authorities[] | select(.tainted == true)')

if [[ -z "$tainted_found" ]]; then
    fail-now "Tainted authority expected"
fi

docker compose exec -T root-server \
    /opt/spire/bin/spire-server localauthority x509 revoke -authorityID $old_authority -output json || fail-now "Failed to revoke authority"

check-log-line root-server "X\.509 authority revoked successfully|local_authority_id=$old_authority"
check-log-line intermediateA-server "X\.509 authority revoked|subject_key_id=$old_authority"
check-log-line intermediateB-server "X\.509 authority revoked|subject_key_id=$old_authority"
check-log-line leafA-server "X\.509 authority revoked|subject_key_id=$old_authority"
check-log-line leafB-server "X\.509 authority revoked|subject_key_id=$old_authority"

servers=("root-server" "intermediateA-server" "intermediateB-server" "leafA-server" "leafB-server")

for server in "${servers[@]}"; do
    retry_count=0
    while [[ $retry_count -lt $MAX_RETRIES ]]; do
        log-debug "Checking if X.509 Authority is revoked on $server"
        x509_authorities_count=$(get-x509-authorities-count $server)

        if [ $x509_authorities_count -eq 1 ]; then
            log-debug "Revoked X.509 Authority successfully on $server"
            break
        else
            retry_count=$((retry_count + 1))
            echo "Revocation is not propagated on $server, retrying in $RETRY_DELAY seconds... ($retry_count/$MAX_RETRIES)"
            sleep $RETRY_DELAY
        fi

        # Fail if retries exceed the maximum
        if [ $retry_count -eq $MAX_RETRIES ]; then
            fail-now "Revocation is not propagated on $server failed after $MAX_RETRIES attempts."
        fi
    done
done
