#!/bin/bash

# Create bundles of federated trust domains to be used by other commands
docker compose exec -T spire-server \
    ash -c "
cat /opt/spire/conf/fixture/ca.pem | 
    /opt/spire/bin/spire-server bundle set -id spiffe://federated1.test" || fail-now "failed to create federated bundle 1"

docker compose exec -T spire-server \
    ash -c "
cat /opt/spire/conf/fixture/ca.pem | 
    /opt/spire/bin/spire-server bundle set -id spiffe://federated2.test" || fail-now "failed to create federated bundle 2"

# Verify entry create
docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry create \
        -selector s1:v1 \
        -parentID spiffe://domain.test/parent \
        -spiffeID spiffe://domain.test/child1 \
        -federatesWith spiffe://federated1.test \
        -admin || fail-now "failed to create entry 1"

docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry create \
        -selector notUpdated:notUpdated \
        -parentID spiffe://domain.test/parentNotUpdated \
        -spiffeID spiffe://domain.test/child2NotUpdated \
        -downstream || fail-now "failed to create entry 2"

docker compose exec -T spire-server \
    /opt/spire/bin/spire-server entry create \
        -selector otherS:otherV \
        -spiffeID spiffe://domain.test/otherChild \
        -node \
        -dns dnsname1 \
        -x509SVIDTTL 123 || fail-now "failed to create entry 3"

# Verify entry count correctly indicates three entries
docker compose exec -T spire-server /opt/spire/bin/spire-server entry count | grep 3 || fail-now "failed to count 3 entries"

# Verify entry show and set variables entryID1, entryID2 and entryID3
# Entry 1
showResult="$(docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry show \
        -spiffeID spiffe://domain.test/child1)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 1"

echo "$showResult" | grep "SPIFFE ID" | grep "spiffe://domain.test/child1" || fail-now "failed to show entry 1, unexpected SPIFFE ID"

echo "$showResult" | grep "Parent ID" | grep "spiffe://domain.test/parent" || fail-now "failed to show entry 1, unexpected Parent ID"

echo "$showResult" | grep "Revision" | grep "0" || fail-now "failed to show entry 1, unexpected Revision number"

echo $(echo "$showResult" | grep "Downstream" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 1, 'grep Downstream' should fail"

echo "$showResult" | grep "TTL" | grep "default" || fail-now "failed to show entry 1, unexpected TTL"

echo "$showResult" | grep "Selector" | grep "s1:v1" || fail-now "failed to show entry 1, expected Selector not found"

echo "$showResult" | grep "FederatesWith" | grep "federated1.test" || fail-now "failed to show entry 1, expected federated domain not found"

echo $(echo "$showResult" | grep "DNS name" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 1, 'grep DNS name' should fail"

echo "$showResult" | grep "Admin" | grep "true" || fail-now "failed to show entry 1, unexpected Admin not true"

entryID1="$(echo "$showResult" | grep "Entry ID")" || fail-now "failed to show entry 1, no Entry ID"
entryID1="${entryID1#*: }"

# Entry 2
showResult="$(docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry show \
        -spiffeID spiffe://domain.test/child2NotUpdated)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 2"

echo "$showResult" | grep "SPIFFE ID" | grep "spiffe://domain.test/child2NotUpdated" || fail-now "failed to show entry 2, unexpected SPIFFE ID"

echo "$showResult" | grep "Parent ID" | grep "spiffe://domain.test/parentNotUpdated" || fail-now "failed to show entry 2, unexpected Parent ID"

echo "$showResult" | grep "Revision" | grep "0" || fail-now "failed to show entry 2, unexpected Revision number"

echo "$showResult" | grep "Downstream" | grep "true" || fail-now "failed to show entry 2, unexpected Downstream not true"

echo "$showResult" | grep "TTL" | grep "default" || fail-now "failed to show entry 2, unexpected TTL"

echo "$showResult" | grep "Selector" | grep "notUpdated:notUpdated" || fail-now "failed to show entry 2, expected Selector not found"

echo $(echo "$showResult" | grep "FederatesWith" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 2, 'grep FederatesWith' should fail"

echo $(echo "$showResult" | grep "DNS name" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 2, 'grep DNS name' should fail"

echo $(echo "$showResult" | grep "Admin" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 2, 'grep Admin' should fail"

entryID2="$(echo "$showResult" | grep "Entry ID")" || fail-now "failed to show entry 2, no Entry ID"
entryID2="${entryID2#*: }"

# Entry 3
showResult="$(docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry show \
        -spiffeID spiffe://domain.test/otherChild)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 3"

echo "$showResult" | grep "SPIFFE ID" | grep "spiffe://domain.test/otherChild" || fail-now "failed to show entry 3, unexpected SPIFFE ID"

echo "$showResult" | grep "Parent ID" | grep "spiffe://domain.test/spire/server" || fail-now "failed to show entry 3, unexpected Parent ID"

echo "$showResult" | grep "Revision" | grep "0" || fail-now "failed to show entry 3, unexpected Revision number"

echo $(echo "$showResult" | grep "Downstream" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 3, 'grep Downstream' should fail"

echo "$showResult" | grep "TTL" | grep "123" || fail-now "failed to show entry 3, unexpected TTL"

echo "$showResult" | grep "Selector" | grep "otherS:otherV" || fail-now "failed to show entry 3, expected Selector not found"

echo $(echo "$showResult" | grep "FederatesWith" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 3, 'grep FederatesWith' should fail"

echo "$showResult" | grep "DNS name" | grep "dnsname1" || fail-now "failed to show entry 3, expected DNS name not found"

echo $(echo "$showResult" | grep "Admin" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 3, 'grep Admin' should fail"

entryID3="$(echo "$showResult" | grep "Entry ID")" || fail-now "failed to show entry 3, no Entry ID"
entryID3="${entryID3#*: }"

# Verify entry update
docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry update \
        -entryID ${entryID1} \
        -selector s1:v1 \
        -parentID spiffe://domain.test/parent \
        -spiffeID spiffe://domain.test/child1 \
        -federatesWith spiffe://federated1.test \
        -x509SVIDTTL 456 || fail-now "failed to update entry 1"

docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry update \
        -entryID ${entryID2} \
        -selector s1:v1 -selector s2:v2 \
        -parentID spiffe://domain.test/parent \
        -spiffeID spiffe://domain.test/child2 \
        -federatesWith spiffe://federated1.test -federatesWith spiffe://federated2.test \
        -dns dnsname2 || fail-now "failed to update entry 2"

docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry update \
        -entryID ${entryID3} \
        -selector otherS:otherV \
        -spiffeID spiffe://domain.test/child3 \
        -parentID spiffe://domain.test/spire/server \
        -admin \
        -downstream || fail-now "failed to update entry 3"

# Verify entry show after updates
# Entry 1
showResult="$(docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry show \
        -spiffeID spiffe://domain.test/child1)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 1 after update"

echo "$showResult" | grep "SPIFFE ID" | grep "spiffe://domain.test/child1" || fail-now "failed to show entry 1 after update, unexpected SPIFFE ID"

echo "$showResult" | grep "Entry ID" | grep ${entryID1} || fail-now "failed to show entry 1 after update, unexpected Entry ID"

echo "$showResult" | grep "Parent ID" | grep "spiffe://domain.test/parent" || fail-now "failed to show entry 1 after update, unexpected Parent ID"

echo "$showResult" | grep "Revision" | grep "1" || fail-now "failed to show entry 1 after update, unexpected Revision number"

echo $(echo "$showResult" | grep "Downstream" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 1 after update, 'grep Downstream' should fail"

echo "$showResult" | grep "TTL" | grep "456" || fail-now "failed to show entry 1 after update, unexpected TTL"

echo "$showResult" | grep "Selector" | grep "s1:v1" || fail-now "failed to show entry 1 after update, expected Selector not found"

echo "$showResult" | grep "FederatesWith" | grep "federated1.test" || fail-now "failed to show entry 1 after update, expected federated domain not found"

echo $(echo "$showResult" | grep "DNS name" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 1 after update, 'grep DNS name' should fail"

echo $(echo "$showResult" | grep "Admin" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 1 after update, 'grep Admin' should fail"

# Entry 2
showResult="$(docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry show \
        -spiffeID spiffe://domain.test/child2)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 2 after update"

echo "$showResult" | grep "SPIFFE ID" | grep "spiffe://domain.test/child2" || fail-now "failed to show entry 2 after update, unexpected SPIFFE ID"

echo "$showResult" | grep "Entry ID" | grep ${entryID2} || fail-now "failed to show entry 1 after update, unexpected Entry ID"

echo "$showResult" | grep "Parent ID" | grep "spiffe://domain.test/parent" || fail-now "failed to show entry 2 after update, unexpected Parent ID"

echo "$showResult" | grep "Revision" | grep "1" || fail-now "failed to show entry 2 after update, unexpected Revision number"

echo $(echo "$showResult" | grep "Downstream" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 2 after update, 'grep Downstream' should fail"

echo "$showResult" | grep "TTL" | grep "default" || fail-now "failed to show entry 2 after update, unexpected TTL"

echo "$showResult" | grep "Selector" | grep "s1:v1" || fail-now "failed to show entry 2 after update, expected Selector 1 not found"

echo "$showResult" | grep "Selector" | grep "s2:v2" || fail-now "failed to show entry 2 after update, expected Selector 2 not found"

echo "$showResult" | grep "FederatesWith" | grep "federated1.test" || fail-now "failed to show entry 2 after update, expected federated domain 1 not found"

echo "$showResult" | grep "FederatesWith" | grep "federated2.test" || fail-now "failed to show entry 2 after update, expected federated domain 2 not found"

echo "$showResult" | grep "DNS name" | grep "dnsname2" || fail-now "failed to show entry 2 after update, expected DNS name not found"

echo $(echo "$showResult" | grep "Admin" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 2 after update, 'grep Admin' should fail"

# Entry 3
showResult="$(docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry show \
        -spiffeID spiffe://domain.test/child3)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 3 after update"

echo "$showResult" | grep "SPIFFE ID" | grep "spiffe://domain.test/child3" || fail-now "failed to show entry 3 after update, unexpected SPIFFE ID"

echo "$showResult" | grep "Entry ID" | grep ${entryID3} || fail-now "failed to show entry 3 after update, unexpected Entry ID"

echo "$showResult" | grep "Parent ID" | grep "spiffe://domain.test/spire/server" || fail-now "failed to show entry 3 after update, unexpected Parent ID"

echo "$showResult" | grep "Revision" | grep "1" || fail-now "failed to show entry 3 after update, unexpected Revision number"

echo "$showResult" | grep "Downstream" | grep "true" || fail-now "failed to show entry 3 after update, unexpected Downstream not true"

echo "$showResult" | grep "TTL" | grep "default" || fail-now "failed to show entry 3 after update, unexpected TTL"

echo "$showResult" | grep "Selector" | grep "otherS:otherV" || fail-now "failed to show entry 3 after update, unexpected Selector"

echo $(echo "$showResult" | grep "FederatesWith" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 3 after update, 'grep FederatesWith' should fail"

echo $(echo "$showResult" | grep "DNS name" || echo "Failed when expected") \
        | grep "Failed when expected" || fail-now "failed to show entry 3 after update, 'grep DNS name' should fail"

echo "$showResult" | grep "Admin" | grep "true" || fail-now "failed to show entry 3 after update, unexpected Admin not true"

# Verify entry show using filters
# By parent
showResult="$(docker compose exec -T spire-server \
        /opt/spire/bin/spire-server entry show \
        -parentID spiffe://domain.test/parent)"

echo "$showResult" | grep "Found 2 entries" || fail-now "failed to show entries by parentID"
echo "$showResult" | grep "Entry ID" | grep ${entryID1} || fail-now "failed to show entries by parentID, expected Entry ID 1 not found"
echo "$showResult" | grep "Entry ID" | grep ${entryID2} || fail-now "failed to show entries by parentID, expected Entry ID 2 not found"

# By selectors (default matcher, SUPERSET)
showResult="$(docker compose exec -T spire-server \
        /opt/spire/bin/spire-server entry show \
        -selector s1:v1)"

echo "$showResult" | grep "Found 2 entries" || fail-now "failed to show entry 1 by selector"
echo "$showResult" | grep ${entryID1} || fail-now "failed to show entry 1 by selector, unexpected Entry ID"
echo "$showResult" | grep ${entryID2} || fail-now "failed to show entry 1 by selector, unexpected Entry ID"

showResult="$(docker compose exec -T spire-server \
        /opt/spire/bin/spire-server entry show \
        -selector s1:v1 -selector s2:v2)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 2 by selector"
echo "$showResult" | grep ${entryID2} || fail-now "failed to show entry 2 by selector, unexpected Entry ID"

# By selectors (change matcher)
showResult="$(docker compose exec -T spire-server \
	/opt/spire/bin/spire-server entry show \
	-selector s1:v1 \
	-matchSelectorsOn exact)"

echo "$showResult" | grep "Found 1 entry" || fail-now "failed to show entry 1 by selector"
echo "$showResult" | grep ${entryID1} || fail-now "failed to show entry 1 by selector, unexpected Entry ID"

# Verify entry delete
showResult="$(docker compose exec -T spire-server \
        /opt/spire/bin/spire-server entry show)"

echo "$showResult" | grep "Found 3 entries" || fail-now "failed to show entries before delete"
echo "$showResult" | grep "Entry ID" | grep ${entryID1} || fail-now "failed to show entries before delete, expected Entry ID 1 not found"
echo "$showResult" | grep "Entry ID" | grep ${entryID2} || fail-now "failed to show entries before delete, expected Entry ID 2 not found"
echo "$showResult" | grep "Entry ID" | grep ${entryID3} || fail-now "failed to show entries before delete, expected Entry ID 3 not found"

docker compose exec -T spire-server \
    /opt/spire/bin/spire-server entry delete \
        -entryID ${entryID1} || fail-now "failed to delete entry 1"

showResult="$(docker compose exec -T spire-server \
        /opt/spire/bin/spire-server entry show)"

echo "$showResult" | grep "Found 2 entries" || fail-now "failed to show entries after delete"
echo "$showResult" | grep "Entry ID" | grep ${entryID2} || fail-now "failed to show entries after delete, expected Entry ID 2 not found"
echo "$showResult" | grep "Entry ID" | grep ${entryID3} || fail-now "failed to show entries after delete, expected Entry ID 3 not found"

# Verify entry count correctly indicates two entries
docker compose exec -T spire-server /opt/spire/bin/spire-server entry count | grep 2 || fail-now "failed to count 2 entries"
