#!/usr/bin/env bash
trap 'killm f' EXIT
#
# File CLA Loopback Test
#
# Tests that bundles can be sent and received via the File CLA using
# the simple file provider library.
#
# Copyright (c) 2025, California Institute of Technology.
# ALL RIGHTS RESERVED.  U.S. Government Sponsorship acknowledged.
#

# documentation boilerplate
CONFIGFILES=" \
./config/loopback.ionrc \
./config/loopback.bprc \
./config/loopback.ipnrc \
"
echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: Testing the File CLA with a simple file provider library."
echo
echo "CONFIG: Custom loopback configuration: "
echo
for N in $CONFIGFILES
do
    echo "$N:"
    cat $N
    echo "# EOF"
    echo
done
echo "OUTPUT: Uses bpsource and bpsink to send and receive a bundle via file."
echo
echo "########################################"

FAIL=0

# Find the stub library - check common locations
SRCDIR="${SRCDIR:-.}"
BUILDDIR="${BUILDDIR:-../..}"

# Try to find the library
if [ -f "${BUILDDIR}/bpv7/file/stub/.libs/libfile_simple_provider.so" ]; then
    STUBLIB="${BUILDDIR}/bpv7/file/stub/.libs/libfile_simple_provider.so"
elif [ -f "${BUILDDIR}/bpv7/file/stub/.libs/libfile_simple_provider.dylib" ]; then
    STUBLIB="${BUILDDIR}/bpv7/file/stub/.libs/libfile_simple_provider.dylib"
elif [ -f "${BUILDDIR}/.libs/libfile_simple_provider.so" ]; then
    STUBLIB="${BUILDDIR}/.libs/libfile_simple_provider.so"
elif [ -f "${BUILDDIR}/.libs/libfile_simple_provider.dylib" ]; then
    STUBLIB="${BUILDDIR}/.libs/libfile_simple_provider.dylib"
else
    echo "ERROR: Cannot find libfile_simple_provider library."
    echo "Make sure to run 'make buildcheck' first to build the test libraries."
    exit 2
fi

echo "Using stub library: ${STUBLIB}"
STUBLIB=$(cd "$(dirname "$STUBLIB")" && pwd)/$(basename "$STUBLIB")
echo "Absolute path: ${STUBLIB}"

# Data file for bundle storage
DATAFILE="/tmp/file_cla_loopback.dat"

# Polling interval in milliseconds
POLL_INTERVAL=500

echo "Killing old ION..."
killm
# Kill any leftover File CLAs from previous runs (use SIGKILL to force)
pkill -9 -f "filecli" 2>/dev/null
pkill -9 -f "fileclo" 2>/dev/null
./cleanup
sleep 1

# Clean up any old data file and generated config
rm -f "${DATAFILE}" ion.log testfile1 testfile2

# Generate runtime bprc with actual library path and data file
CONFIGDIR="./config"
sed -e "s|STUBLIB|${STUBLIB}|g" \
    -e "s|DATAFILE|${DATAFILE}|g" \
    -e "s|POLL_INTERVAL|${POLL_INTERVAL}|g" \
    "${CONFIGDIR}/loopback.bprc" > "${CONFIGDIR}/loopback_runtime.bprc"

echo "Starting ION..."
ionadmin "${CONFIGDIR}/loopback.ionrc"
sleep 1
# loopback_runtime.bprc includes 'r ipnadmin' and 's' commands at the end
bpadmin "${CONFIGDIR}/loopback_runtime.bprc"

# Wait for File CLAs to be running
echo "Waiting for File CLAs to start..."
for i in 1 2 3 4 5 6 7 8 9 10; do
    if pgrep -f "filecli.*loopback" > /dev/null && pgrep -f "fileclo.*loopback" > /dev/null; then
        echo "File CLAs are running."
        break
    fi
    echo "  Waiting... ($i)"
    sleep 1
done
sleep 2

echo "Creating test file..."
echo "This is a test message for File CLA loopback" > testfile1

echo "Starting bpsink..."
bpsink ipn:1.1 > testfile2 &
BPSINK_PID=$!
sleep 1

echo "Sending bundle via bpsource..."
echo "NOTE: The provider will report sent/received byte counts with CRC32 checksums."
echo "      Frame format: [4-byte length][4-byte length CRC][data][4-byte data CRC]"
bpsource ipn:1.1 "This is a test message for File CLA loopback"
sleep 3

echo "Checking received data..."
if grep -q "This is a test message for File CLA loopback" testfile2; then
    echo "SUCCESS: Bundle received correctly via File CLA loopback!"
else
    echo "ERROR: Bundle not received or content mismatch."
    echo "Expected: This is a test message for File CLA loopback"
    echo "Received:"
    cat testfile2
    FAIL=1
fi

# Optionally inspect the data file
if [ -f "${DATAFILE}" ]; then
    echo ""
    echo "Data file contents (hex dump of first 128 bytes):"
    xxd -l 128 "${DATAFILE}" 2>/dev/null || hexdump -C -n 128 "${DATAFILE}" 2>/dev/null || echo "(hexdump not available)"
fi

echo "Cleaning up..."
kill $BPSINK_PID 2>/dev/null
sleep 1

# Kill the File CLAs explicitly (use SIGKILL - they may be blocked on file reads)
pkill -9 -f "filecli" 2>/dev/null
pkill -9 -f "fileclo" 2>/dev/null
sleep 1

ionstop
sleep 1
killm

# Clean up
rm -f "${DATAFILE}" testfile1 testfile2
rm -f "${CONFIGDIR}/loopback_runtime.bprc"

exit $FAIL
