#!/usr/bin/env bash
trap 'killm f' EXIT
#
# LTP Cancel Segment Acknowledgment Regression Test
# Tests fix for issue where Cancel Segments for completed sessions were ignored
#

CONFIGFILES=" \
./2.ipn.ltp/amroc.ltprc \
./2.ipn.ltp/amroc.bprc \
./2.ipn.ltp/amroc.ionconfig \
./2.ipn.ltp/global.ionrc \
./2.ipn.ltp/amroc.ionrc \
./2.ipn.ltp/amroc.ionsecrc \
./2.ipn.ltp/amroc.ipnrc \
./3.ipn.ltp/amroc.ltprc \
./3.ipn.ltp/amroc.bprc \
./3.ipn.ltp/amroc.ionconfig \
./3.ipn.ltp/global.ionrc \
./3.ipn.ltp/amroc.ionrc \
./3.ipn.ltp/amroc.ionsecrc \
./3.ipn.ltp/amroc.ipnrc \
"

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: Testing LTP Cancel Segment acknowledgment for completed sessions.
    This test verifies the fix for issue where Cancel Segments received
    after sessions were completed were being ignored, causing unnecessary
    retransmissions and resource consumption. The LTP engine should always
    acknowledge Cancel Segments regardless of session state."
echo
echo "CONFIG: 2 node custom:"
echo
for N in $CONFIGFILES
do
    echo "$N:"
    cat "$N"
    echo "# EOF"
    echo
done

echo "Checking test prerequisites..."

# Find the latest available Python 3 version >= 3.10
PYTHON_CMD="python3"

if command -v "$PYTHON_CMD" &> /dev/null; then
    py_maj=$("$PYTHON_CMD" -c 'import sys; print(sys.version_info[0])' 2>/dev/null)
    py_min=$("$PYTHON_CMD" -c 'import sys; print(sys.version_info[1])' 2>/dev/null)

    if [ "$py_maj" = "3" ] && [ "$py_min" -ge 10 ]; then
        PYTHON_VERSION="3.$py_min"
    else
        PYTHON_CMD=""
    fi
else
    PYTHON_CMD=""
fi

if [ -z "$PYTHON_CMD" ]; then
    echo "SKIP: Python 3.10 or higher is required but not found."
    exit 2
fi

echo "Using Python $PYTHON_VERSION (via $PYTHON_CMD)"
echo

# Cleanup
./cleanup
sleep 1

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

# Start Node 2 (sender)
echo "Starting node 2..."
cd 2.ipn.ltp
./ionstart > node2.stdout 2>&1 &
sleep 3
../../../system_up -i "p 30" -l "p 30" -b "p 30" 2.ipn.ltp
if [ $? -ne 3 ]; then
    echo "Error: Node 2 failed to start properly"
    # Preserve logs on failure (runtests handles cleanup; killm trap stops ION).
    # ./cleanup
    exit 1
fi
cd ..

# Start Node 3 (receiver)
echo "Starting node 3..."
cd 3.ipn.ltp
./ionstart > node3.stdout 2>&1 &
sleep 3
../../../system_up -i "p 30" -l "p 30" -b "p 30" 3.ipn.ltp
if [ $? -ne 3 ]; then
    echo "Error: Node 3 failed to start properly"
    # Preserve logs on failure (see note above).
    # ./cleanup
    exit 1
fi
cd ..

echo "Nodes started successfully"

RETVAL=0

# Use unique test ports that don't conflict with ION's ports
TEST_PORT_NODE2=2114
TEST_PORT_NODE3=3114

echo ""
echo "Running cancel segment acknowledgment tests..."
echo "Using test ports: Node2=$TEST_PORT_NODE2, Node3=$TEST_PORT_NODE3"

# Scenario A: CS for unknown session
echo "=== Test Scenario: CS for unknown session (should NOT be acknowledged) ==="
python3 runtest.py --send-cancel-only --cancel-type CS --dest-port 3113 --engine-id 2 --session-id 99999
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
    echo "FAILURE: Failed to send CS segment"
fi
sleep 2

# Scenario B: CR for unknown session
python3 runtest.py --scenario "CR for unknown session" --cancel-type CR --dest-port 2113 --ack-port $TEST_PORT_NODE3 --engine-id 3 --session-id 99998
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
    echo "FAILURE: CR test failed"
fi
sleep 2

# Scenario C: CS after sending some data (simulate completed session)
echo "=== Sending test data to create session activity ==="
python3 runtest.py --generate-data --dest-port 3113 --engine-id 2 --session-id 1
sleep 3

# Test CS for potentially completed session
python3 runtest.py --scenario "CS after data transfer" --cancel-type CS --dest-port 3113 --ack-port $TEST_PORT_NODE2 --engine-id 2 --session-id 1
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
    echo "FAILURE: CS after data transfer test failed"
fi
sleep 2

# Scenario D: CR after data transfer
python3 runtest.py --scenario "CR after data transfer" --cancel-type CR --dest-port 2113 --ack-port $TEST_PORT_NODE3 --engine-id 3 --session-id 1
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
    echo "FAILURE: CR after data transfer test failed"
fi

echo ""
# End-of-test cleanup removed: runtests runs ./cleanup after a pass (unless
# PRESERVE_TEST_LOGS=1) and preserves logs on failure; the initial ./cleanup
# above gives a clean slate for manual runs.
# ./cleanup

echo ""
if [ $RETVAL -eq 0 ]; then
    echo "ALL TESTS PASSED: LTP properly acknowledges Cancel Segments"
elif [ $RETVAL -eq 2 ]; then
    echo "bespokebpv7 not installed, test skipped"
else
    echo "SOME TESTS FAILED: Cancel segment acknowledgment issue detected"
fi

exit $RETVAL
