#!/bin/sh

set -eu

UDPSERVER_PORT=5500
UDPTUNNEL_SRV_TCP_PORT=6491
UDPTUNNEL_CLI_UDP_PORT=6661

TX_FILE="$AUTOPKGTEST_TMP/tx.data"
RX_FILE="$AUTOPKGTEST_TMP/rx.data"

STATUS_ERROR=1
STATUS_SKIP=77

wait_port_open() {
    port="$1"
    proto="$2"

    MAXTRY=10
    itry=0

    while [ $itry -lt $MAXTRY ]; do
        netstat --$proto -ln | grep $port > /dev/null && break

        itry=$(($itry + 1))
        sleep 1
    done

    if [ "$itry" -eq "$MAXTRY" ]; then
        echo "Port $port/$proto could not be opened; checked $MAXTRY times"
        echo "ending $0 with status $STATUS_SKIP"
        exit $STATUS_SKIP
    fi

    echo "Port $port/$proto opened"
}

start_udp_server() {
    ncat -u -l 127.0.0.1 $UDPSERVER_PORT -o $RX_FILE &
    udp_server_pid="$!"

    wait_port_open $UDPSERVER_PORT udp
}

start_udptunnel_server() {
    udptunnel -s $UDPTUNNEL_SRV_TCP_PORT 127.0.0.1/$UDPSERVER_PORT &
    udptunnel_server_pid="$!"

    wait_port_open $UDPTUNNEL_SRV_TCP_PORT tcp
}

start_udptunnel_client() {
    udptunnel -c 127.0.0.1/$UDPTUNNEL_SRV_TCP_PORT 127.0.0.1/$UDPTUNNEL_CLI_UDP_PORT &
    udptunnel_client_pid="$!"

    wait_port_open $UDPTUNNEL_CLI_UDP_PORT udp
}

make_tx_file() {
# trailing whitespaces were left on purpose
cat <<EOF >> $TX_FILE
THIS  
 IS  
  THE  
   DATA 
    SEND 
     OVER 
      UDPTunnel 
EOF
}

transmit_udp_data() {
    make_tx_file
    cat $TX_FILE | ncat -u 127.0.0.1 $UDPTUNNEL_CLI_UDP_PORT
}

received_udp_data() {
    diff $TX_FILE $RX_FILE

    return $?
}

test_communication() {
    transmit_udp_data
    # Wait for the file be written. More info in #1094138
    sleep 1

    if ! received_udp_data; then
        # To ensure it was a failure, wait more and check again
        sleep 10
        if ! received_udp_data; then
            echo "UDPTunnel communication failed"
            echo "ending $0 with status $STATUS_ERROR"
            exit $STATUS_ERROR
        fi
    fi

    echo "UDPTunnel communication success"
}

clean() {
    kill -9 $udp_server_pid || true
    kill -9 $udptunnel_server_pid || true
    kill -9 $udptunnel_client_pid || true
    rm -f $AUTOPKGTEST_TMP/*
}

## main
start_udp_server
start_udptunnel_server
start_udptunnel_client

test_communication
clean

exit 0
