#!/usr/bin/env bash
trap 'killm f' EXIT
#
# custody-bundle-query: bpadmin l custodybundle / i custodybundle commands (G7)
#
# Verifies (G7):
#   cbr_listCustodyBundles and cbr_getCustodyStatus are surfaced via bpadmin
#   as 'l custodybundle' and 'i custodybundle <custodianEid> <seqId> <seqNum>'.
#   The lookup key is the BSN-provider (custodian) admin EID -- the AEID this
#   node wrote into the CTEB -- not the bundle's primary-block source EID.
#   Per Orange Book 4.2.4 the returning CCS omits that AEID, so custody is
#   tracked and queried under the local admin EID (ipn:1.0 here), not ipn:1.2.
#
# This test exercises both commands by putting bundles into Node 1's custody
# tracking, then querying them while they are pending:
#
#   - Node 1 sends 2 custody bundles (seqId=1, seqNums 0 and 1) to Node 2.
#   - Node 2 refuses custody via a whitelist that excludes ipn:1.0.
#   - Node 1 uses cbrretx=none so refused bundles remain in custody tracking.
#   - 'l custodybundle' at Node 1 must show both bundles.
#   - 'i custodybundle ipn:1.0 1 0' must report "pending".
#   - 'i custodybundle ipn:1.0 1 99' (not tracked) must report "not-found".
#
# Topology: Node 1 (source, RETX_NONE) -> Node 2 (refuses via whitelist)
#

TESTDIR=$(cd "$(dirname "$0")" && pwd)
export ION_NODE_LIST_DIR="$TESTDIR"

echo "=== Custody Bundle Query Test (G7) ==="
echo "Topology: Node 1 (RETX_NONE) -> Node 2 (custody refused via whitelist)"
echo ""

./cleanup

TESTS_PASSED=0
TESTS_FAILED=0

test_result() {
    if [ $1 -eq 0 ]; then
        TESTS_PASSED=$((TESTS_PASSED + 1))
        echo "  PASS: $2"
    else
        TESTS_FAILED=$((TESTS_FAILED + 1))
        echo "  FAIL: $2"
    fi
}

echo "Starting ION nodes..."
for node in 1 2; do
    cd "$TESTDIR/${node}.node"
    chmod +x ionstart
    ./ionstart > ion_startup.log 2>&1
    sleep 2
done

NODE_COUNT=$(pgrep -f "rfxclock" | wc -l)
if [ "$NODE_COUNT" -lt 2 ]; then
    echo "ERROR: Not all ION nodes started. Found $NODE_COUNT rfxclock processes."
    exit 1
fi
echo "Both nodes started successfully."
echo ""

# ---------------------------------------------------------------
echo "--- Phase 1: Send 2 custody bundles from Node 1 to Node 2 ---"
echo "  Node 2 will refuse custody (whitelist excludes ipn:1.0)"

cd "$TESTDIR/1.node"

bptrace -seqid 1 -msg "G7-B1" -ttl 60 -qos 1.1 ipn:1.2 ipn:2.1 ipn:1.0 > /dev/null 2>&1
bptrace -seqid 1 -msg "G7-B2" -ttl 60 -qos 1.1 ipn:1.2 ipn:2.1 ipn:1.0 > /dev/null 2>&1

echo "  2 bundles sent."
echo "  Waiting for CCS refusal to arrive at Node 1..."
sleep 15

# ---------------------------------------------------------------
echo ""
echo "--- Test 1: Custody refusal received at Node 1 ---"

if grep -Fq 'CCS: Custody refused by next hop' "$TESTDIR/1.node/ion.log" 2>/dev/null; then
    test_result 0 "Custody-refused CCS received at Node 1"
else
    test_result 1 "No custody-refused CCS seen at Node 1 (prerequisite for query tests)"
fi

# ---------------------------------------------------------------
echo ""
echo "--- Test 2: l custodybundle shows entries at Node 1 ---"

cd "$TESTDIR/1.node"
LIST_OUT=$(echo 'l custodybundle' | bpadmin 2>/dev/null)
echo "  l custodybundle output:"
echo "$LIST_OUT" | sed 's/^/    /'

ENTRY_COUNT=$(echo "$LIST_OUT" | grep -c 'seqId=' || true)
ENTRY_COUNT=${ENTRY_COUNT:-0}

if [ "$ENTRY_COUNT" -ge 2 ]; then
    test_result 0 "l custodybundle shows $ENTRY_COUNT entries (expected >= 2)"
else
    test_result 1 "l custodybundle shows $ENTRY_COUNT entries, expected >= 2"
fi

# ---------------------------------------------------------------
echo ""
echo "--- Test 3: i custodybundle reports 'pending' for tracked bundle ---"

cd "$TESTDIR/1.node"
INFO_OUT=$(echo 'i custodybundle ipn:1.0 1 0' | bpadmin 2>/dev/null)
echo "  i custodybundle ipn:1.0 1 0 output:"
echo "$INFO_OUT" | sed 's/^/    /'

if echo "$INFO_OUT" | grep -Fq 'pending'; then
    test_result 0 "i custodybundle ipn:1.0 1 0 reports pending"
else
    test_result 1 "i custodybundle ipn:1.0 1 0 did not report pending"
fi

# ---------------------------------------------------------------
echo ""
echo "--- Test 4: i custodybundle reports 'not-found' for untracked seqNum ---"

cd "$TESTDIR/1.node"
INFO_OUT=$(echo 'i custodybundle ipn:1.0 1 99' | bpadmin 2>/dev/null)
echo "  i custodybundle ipn:1.0 1 99 output:"
echo "$INFO_OUT" | sed 's/^/    /'

if echo "$INFO_OUT" | grep -Fq 'not-found'; then
    test_result 0 "i custodybundle ipn:1.0 1 99 reports not-found"
else
    test_result 1 "i custodybundle ipn:1.0 1 99 did not report not-found"
fi

# ---------------------------------------------------------------
echo ""
echo "--- Test 5: No ION errors at either node ---"

for node in 1 2; do
    ERR=$(grep -c '\[!' "$TESTDIR/${node}.node/ion.log" 2>/dev/null)
    ERR=${ERR:-0}
    if [ "$ERR" -gt 0 ]; then
        echo "  ${node}.node: $ERR error(s)"
        grep '\[!' "$TESTDIR/${node}.node/ion.log" | head -5 | sed 's/^/    /'
    else
        echo "  ${node}.node: no errors"
    fi
    test_result "$ERR" "No ION errors at Node $node"
done

echo ""
echo "========================================="
echo "SUMMARY: $TESTS_PASSED passed, $TESTS_FAILED failed"
echo "========================================="

[ $TESTS_FAILED -eq 0 ]
