#!/bin/bash

MAX_RETRIES=10
RETRY_DELAY=2 # seconds between retries

fetch-active-authority() {
    docker compose exec -T root-server \
        /opt/spire/bin/spire-server localauthority x509 show -output json | jq -r .active.authority_id
}

validate-agent() {
    local agent=$1
    local retry_count=0

    while [[ $retry_count -lt $MAX_RETRIES ]]; do
        docker compose exec -u 1001 -T $agent \
            /opt/spire/bin/spire-agent api fetch x509 \
            -socketPath /opt/spire/sockets/workload_api.sock \
            -write /tmp || fail-now "x509-SVID check failed for $agent"

        local bundle_count=$(docker compose exec -T $agent \
            openssl storeutl -noout -text -certs /tmp/bundle.0.pem | grep -c "Certificate:")
        if [ $bundle_count -eq 1 ]; then
            log-debug "Validation successful for $agent: There is exactly one certificate in the chain."
            return 0
        else
            log-debug "Validation failed for $agent: Expected 1 certificate, but found $bundle_count. Retrying in $RETRY_DELAY seconds... ($retry_count/$MAX_RETRIES)"
        fi

        retry_count=$((retry_count + 1))
        sleep $RETRY_DELAY

        if [ $retry_count -eq $MAX_RETRIES ]; then
            fail-now "Validation failed for $agent: Expected 1 certificate, but found $bundle_count."
        fi
    done
}

check_ski() {
    local agent=$1
    local old_authority=$2

    local ski=$(docker compose exec -T $agent \
	    openssl x509 -in /tmp/bundle.0.pem -text | grep \
	    -A 1 'Subject Key Identifier' | tail -n 1 | tr -d ' ' | tr -d ':' | tr '[:upper:]' '[:lower:]')

    if [ "$ski" == "$old_authority" ]; then
        log-debug "Subject Key Identifier matches for $agent: $ski"
    else
        fail-now "Subject Key Identifier does not match for $agent. Found: $ski Expected: $old_authority"
    fi
}

active_authority=$(fetch-active-authority)
log-debug "Active authority: $active_authority"

agents=("root-agent" "intermediateA-agent" "intermediateB-agent" "leafA-agent" "leafB-agent")
for agent in "${agents[@]}"; do
    validate-agent "$agent"
    check_ski "$agent" "$active_authority"
done
