#!/usr/bin/env bash
trap 'killm f' EXIT
#
# bpsec-bcb-only.bsl
#
# BSL BCB-only test: exercises BCB (confidentiality) processing WITHOUT any
# BIB (integrity) blocks. This fills a coverage gap since the existing
# bpsec-all-multinode-test.bsl always pairs BIB+BCB.
#
# Topology:
#   Node 2 (ipn:2.*) --LTP--> Node 3 (ipn:3.*) --LTP--> Node 4 (ipn:4.*)
#
# Security design:
#   Node 2: BCB source on payload (tgt 1) for 2->3 and 2->4
#   Node 3: BCB verifier at CLIN + acceptor at APPOUT for direct delivery;
#           BCB relay verifier at CLIN for 2->4 transit
#   Node 4: BCB verifier at CLIN + acceptor at APPOUT
#
# Tests:
#   Test 1 - BCB on payload, node 2->3
#   Test 2 - BCB on payload, node 2->4 via relay (node 3 verifies, no decrypt)
#   Test 3 - Large ~4MB file with BCB on payload, node 2->3

TIMETODISPLAYTEXT=2
TIMETOWAITFORTESTFINISH=5

echo "Cleaning up old ION..."
rm -f 2.ipn.ltp/ion.log 3.ipn.ltp/ion.log 4.ipn.ltp/ion.log
killm
sleep 1

echo "Starting ION..."
export ION_NODE_LIST_DIR=$PWD
rm -f ./ion_nodes

BSL_KEY_FILE="${PWD}/key_set.json"
if [ ! -f "$BSL_KEY_FILE" ]; then
    echo "ERROR: BSL key file not found: $BSL_KEY_FILE"
    exit 2
fi

for pf in "${PWD}/policy_node2.json" "${PWD}/policy_node3.json" "${PWD}/policy_node4.json"; do
    if [ ! -f "$pf" ]; then
        echo "ERROR: BSL policy file not found: $pf"
        exit 2
    fi
done

PASS=1

cd 2.ipn.ltp
ionadmin amroc.ionrc
cd ../3.ipn.ltp
ionadmin amroc.ionrc
cd ../4.ipn.ltp
ionadmin amroc.ionrc

cd ../2.ipn.ltp
ionadmin ../global.ionrc
cd ../3.ipn.ltp
ionadmin ../global.ionrc
cd ../4.ipn.ltp
ionadmin ../global.ionrc

cd ../2.ipn.ltp
ionsecadmin amroc.ionsecrc
cd ../3.ipn.ltp
ionsecadmin amroc.ionsecrc
cd ../4.ipn.ltp
ionsecadmin amroc.ionsecrc

cd ../2.ipn.ltp
ltpadmin amroc.ltprc
cd ../3.ipn.ltp
ltpadmin amroc.ltprc
cd ../4.ipn.ltp
ltpadmin amroc.ltprc

cd ../2.ipn.ltp
bpadmin amroc.bprc
cd ../3.ipn.ltp
bpadmin amroc.bprc
cd ../4.ipn.ltp
bpadmin amroc.bprc

cd ..

rm -f 3.ipn.ltp/3_receive_file.txt
rm -f 3.ipn.ltp/3_results.txt
touch 3.ipn.ltp/3_receive_file.txt
touch 3.ipn.ltp/3_results.txt

echo "Starting bpsink on node 3..."
cd 3.ipn.ltp
bpsink ipn:3.1 >> 3_results.txt &
cd ..

sleep 1

#############
# Test 1: BCB on payload, node 2->3

cd 2.ipn.ltp
echo -e "\n\n*****TEST 1*****"
echo "BCB on payload block, node 2->3. Should be delivered (decrypted)."
sleep ${TIMETODISPLAYTEXT}
bptrace ipn:2.1 ipn:3.1 ipn:2.0 5 0.1 "bcb_payload_test1" rcv,ct,fwd,dlv,del
cd ..

sleep ${TIMETOWAITFORTESTFINISH}

grep "bcb_payload_test1" 3.ipn.ltp/3_results.txt > 3.ipn.ltp/3_receive_file.txt

rm -f expected.txt
echo "'bcb_payload_test1'" > expected.txt

if ! diff -w expected.txt 3.ipn.ltp/3_receive_file.txt; then
    echo "FAIL (test 1)"
    PASS=0
else
    echo "SUCCESS (test 1)"
fi

##############################
# Test 2: BCB on payload through relay, node 2->4 via node 3

rm -f 4.ipn.ltp/4_receive_file.txt
rm -f 4.ipn.ltp/4_results.txt
touch 4.ipn.ltp/4_receive_file.txt
touch 4.ipn.ltp/4_results.txt

echo "Starting bpsink on node 4..."
cd 4.ipn.ltp
bpsink ipn:4.1 >> 4_results.txt &
cd ..

sleep 1

echo -e "\n\n*****TEST 2*****"
echo "BCB on payload, node 2->4 via relay. Node 3 verifies BCB (no decrypt). Should be delivered."
sleep ${TIMETODISPLAYTEXT}

cd 2.ipn.ltp
bptrace ipn:2.1 ipn:4.1 ipn:2.0 5 0.1 "bcb_relay_test2" rcv,ct,fwd,dlv,del
cd ..

sleep ${TIMETOWAITFORTESTFINISH}

grep "bcb_relay_test2" 4.ipn.ltp/4_results.txt > 4.ipn.ltp/4_receive_file.txt

rm -f expected.txt
echo "'bcb_relay_test2'" > expected.txt

if ! diff -w expected.txt 4.ipn.ltp/4_receive_file.txt; then
    echo "FAIL (test 2)"
    PASS=0
else
    echo "SUCCESS (test 2)"
fi

##############################
# Test 3: Large file with BCB on payload, node 2->3

echo -e "\n\n*****TEST 3*****"
echo "Large ~100KB file with BCB on payload, node 2->3. Should be delivered intact."
sleep ${TIMETODISPLAYTEXT}

cd 3.ipn.ltp
bprecvfile ipn:3.2 &
cd ..

sleep 1

cd 2.ipn.ltp

perl -e 'print "A" x (100 * 1024)' > hugefile.big

bpsendfile ipn:2.1 ipn:3.2 hugefile.big

sleep 15

cd ..

PROGRAMTEST="stat"
RESULTS=$(which ${PROGRAMTEST} 2>/dev/null)
if [ -z "${RESULTS}" ]; then
    RECV_SIZE=$(ls -1l 3.ipn.ltp/testfile1 2>/dev/null | sed 's/ [ ]*/ /g' | cut -d' ' -f5)
    SEND_SIZE=$(ls -1l 2.ipn.ltp/hugefile.big | sed 's/ [ ]*/ /g' | cut -d' ' -f5)
else
    RECV_SIZE=$(stat -c %s 3.ipn.ltp/testfile1 2>/dev/null)
    SEND_SIZE=$(stat -c %s 2.ipn.ltp/hugefile.big)
fi

echo "Receive size: $RECV_SIZE; Send size: $SEND_SIZE"
if [ "$RECV_SIZE" = "$SEND_SIZE" ]; then
    echo "SUCCESS (test 3)"
else
    echo "FAIL (test 3)"
    PASS=0
fi

rm -f 2.ipn.ltp/hugefile.big
rm -f 3.ipn.ltp/testfile1

############################################################
# END OF TESTS

echo "Stopping ION..."
cd 2.ipn.ltp
./ionstop &
cd ../3.ipn.ltp
./ionstop &
cd ../4.ipn.ltp
./ionstop &

cd ..

sleep 7
killm
echo "BCB-only test completed."

if [ $PASS -eq 1 ]; then
    exit 0
else
    exit 1
fi
