#!/bin/sh

# Tests a set of commands listed in the recording/basic.input file
# and runs those commands through the rtpp control channel, comparing
# the results with the expected results contained in the
# recording/basic.output file.

BASEDIR="${BASEDIR:-$(dirname -- $0)/..}"
BASEDIR="$(readlink -f -- $BASEDIR)"

. $(dirname $0)/../functions

PCAP_DIR1="${BASEDIR}/rtp_analyze"
PCAP_DIR2="${BASEDIR}/acct_rtcp_hep"
CD_DIR="${BASEDIR}/recording"
RECSIZE=109564

run_udpreplay() {
  direction=${1}
  rtp_oport1=${2}
  rtp_oport2=${3}
  rtp_nport=${4}
  rtcp_oport1=$((${rtp_oport1} + 1))
  rtcp_oport2=$((${rtp_oport2} + 1))
  rtcp_nport=$((${rtp_nport} + 1))
  #UDPREPLAY_ARGS="-o udpreplay_${direction}.pcap"
  tcprewrite --dstipmap=0.0.0.0/0:127.0.0.1 --portmap=${rtp_oport1}:${rtp_nport} --portmap=${rtcp_oport1}:${rtcp_nport} \
   -i "${PCAP_DIR1}/srtp1.${direction}.rtp" -o recording.1.${rtp_nport}.${direction}.pcap || return 1
  tcprewrite --dstipmap=0.0.0.0/0:127.0.0.1 --portmap=${rtp_oport2}:${rtp_nport} --portmap=${rtcp_oport2}:${rtcp_nport} \
   -i "${PCAP_DIR2}/rtcp.${direction}.pcap" -o recording.2.${rtp_nport}.${direction}.pcap || return 1
  if [ "${direction}" = "o" ]
  then
    NPKTS1=300
    NPKTS2=163
  else
    NPKTS1=302
    NPKTS2=159
  fi
  sleep 1
  udpreplay -r 2 -n ${NPKTS1} ${UDPREPLAY_ARGS} recording.1.${rtp_nport}.${direction}.pcap
  sleep 2
  exec udpreplay -r 2 -n ${NPKTS2} ${UDPREPLAY_ARGS} recording.2.${rtp_nport}.${direction}.pcap
}

run_rtpproxy() {
  rname="${1}"
  rtp_porta=${2}
  rtp_porto=${3}
  rproto=${4}
  rport=${5}
  rtp_port_rec=${6}
  recstop=

  case "${rproto}" in
  files*)
    if [ "${rproto}" = "files_stophalf" ]
    then
      recstop=half1
      rproto="files"
    fi
    for rdircn in 'a' 'o'
    do
      for rtype in 'rtcp' 'rtp'
      do
        recfile="${rname}.${rdircn}.${rtype}"
        if [ -e "${recfile}" ]
        then
          rm "${recfile}" || return 1
        fi
      done
    done
    ;;

  singlefile*|stopall)
    if [ "${rproto}" = "stopall" ]
    then
      recstop=all
    fi
    if [ "${rproto}" = "singlefile_stophalf" ]
    then
      recstop=half2
      rproto="singlefile"
    fi
    recfile="${rname}.pcap"
    if [ -e "${recfile}" ]
    then
      rm "${recfile}" || return 1
    fi
    ;;
  esac

  (cat "${CD_DIR}/basic.input" "${CD_DIR}/basic.${rproto}.input"; \
   sleep 8; cat "${CD_DIR}/basic.stats.input" "${CD_DIR}/basic.recstop${recstop}.input" \
    "${CD_DIR}/basic.refresh.input"; \
   sleep 7; cat "${CD_DIR}/basic.stats.input") | \
   sed -u "s|%%CALLID%%|${CALL_ID}|g ; s|%%REC_PORT%%|${rport}|g ; \
    s|%%REC_NAME%%|${recfile}|g" | \
    ${RTPPROXY} ${RTPP_ARGS} ${RTPP_REC_ARGS} | sed \
    "s|^${rtp_porta}$|%%PORT_A%%|g ; s|^${rtp_porto}$|%%PORT_O%%|g ; \
     s|^${rtp_port_rec}|%%PORT_REC%%|g"

  case "${rproto}" in
  files)
    for rdircn in 'a' 'o'
    do
      for rtype in 'rtcp' 'rtp'
      do
        recfile="${rname}.${rdircn}.${rtype}"
        (env RTPP_GLITCH_ACT="" ${EXTRACTAUDIO} -S -A "${recfile}" || return 1) | \
         sed "s|${CALL_ID}|%%CALL_ID%%|g"
      done
    done
    ;;

  singlefile|singlefile_c|stopall)
    recfile="${rname}.pcap"
    if [ -e "${recfile}" ]
    then
      (env RTPP_GLITCH_ACT="" ${EXTRACTAUDIO} -S -A "${recfile}" || return 1) | \
       sed "s|${CALL_ID}|%%CALL_ID%%|g"
    fi
    ;;
  esac
}

run_recording() {
  REC_PROTO="${1}"
  RTP_PORT=`${PYINT} -c "from random import random;m=10000;print(m+(int(random()*((65536-m)/4)) * 4))"`
  REC_PORT=`${PYINT} -c "from random import random;m=10000;print(m+int(random()*(65536-m)))"`
  CALL_ID="recording.${REC_PROTO}_${REC_PORT}.rec."
  RECNAME="${CALL_ID}=from_tag_1"
  MIN_PORT=$((${RTP_PORT}))
  MAX_PORT=$((${RTP_PORT} + 7))
  RTP_PORT_A=${RTP_PORT}
  RTP_PORT_O=$((${RTP_PORT} + 2))
  RTP_PORT_REC=$((${RTP_PORT} + 6))
  RTPP_REC_ARGS="-P -r ${RECORD_DIR} -S ${RECORD_SPL_DIR}"

  ONAME="recording.${REC_PORT}.${REC_PROTO}.rout"
  TNAME="recording.${REC_PORT}.${REC_PROTO}.tlog"
  LNAME="recording.${REC_PROTO}.rlog"
  RTPP_ARGS="-d dbug -f -s stdio: -b -m ${MIN_PORT} \
   -M ${MAX_PORT} -T2 -W2"

  if [ "${REC_PROTO}" = "remote" -o "${REC_PROTO}" = "remote_p" ]
  then
    NC_ARGS="-k -u -l 127.0.0.1 ${REC_PORT}"
    nc ${NC_ARGS} > ${TNAME}&
    RTPP_NC_RC=${?}
    RTPP_NC_PID=${!}
    sleep 0.2
    report_rc ${RTPP_NC_RC} "Starting NetCat on port ${REC_PORT}/udp"
  fi
  run_udpreplay a 2280 2006 ${RTP_PORT_A} &
  UDPRPL_A_RC=${?}
  UDPRPL_A_PID=${!}
  report_rc ${UDPRPL_A_RC} "Starting udpreplay (answering) to ${RTP_PORT_A}/rtp"
  run_udpreplay o 2240 2008 ${RTP_PORT_O} &
  UDPRPL_O_RC=${?}
  UDPRPL_O_PID=${!}
  report_rc ${UDPRPL_O_RC} "Starting udpreplay (originate) to ${RTP_PORT_O}/rtp"
  run_rtpproxy "${RECNAME}" ${RTP_PORT_A} ${RTP_PORT_O} "${REC_PROTO}" \
    "${REC_PORT}" "${RTP_PORT_REC}" > "${ONAME}" 2> "${LNAME}"
  RTPP_RC=${?}
  ${DIFF} "${CD_DIR}/basic.${REC_PROTO}.output" "${ONAME}"
  DIFF_RC=${?}
  if [ ${RTPP_RC} -ne 0 -o ${DIFF_RC} -ne 0 ]
  then
    kill -KILL ${UDPRPL_A_PID} ${UDPRPL_O_PID} ${RTPP_NC_PID} 2>/dev/null
    if [ -e "${LNAME}" ]
    then
      cat "${LNAME}"
    fi
  fi
  report_rc ${RTPP_RC} "wait for the rtproxy shutdown"
  report_rc ${DIFF_RC} "checking rtproxy output"
  if [ "${REC_PROTO}" = "remote" -o "${REC_PROTO}" = "remote_p" ]
  then
    kill -TERM ${RTPP_NC_PID} 2>/dev/null
    ##wait ${RTPP_NC_PID}
    report "wait for NetCat shutdown"
  fi
  wait ${UDPRPL_A_PID}
  report "wait for udpreplay (answering) shutdown"
  wait ${UDPRPL_O_PID}
  report "wait for udpreplay (originate) shutdown"
  if [ "${REC_PROTO}" = "remote" -o "${REC_PROTO}" = "remote_p" ]
  then
    recsize=`wc -c "${TNAME}"| awk '{print $1}'`
    if [ ${recsize} -ne ${RECSIZE} ]
    then
      forcefail 1 "Incorrect recording size, ${RECSIZE} expected, ${recsize} obtained"
    fi
    report "checking recording size"
  fi
}

SUB_TESTS="${SUB_TESTS:-"files singlefile singlefile_c stopall files_stophalf singlefile_stophalf remote remote_p"}"

for stest in ${SUB_TESTS}
do
  run_recording ${stest} &
  T_RC=${?}
  eval ${stest}_PID=${!}
  report_rc "${T_RC}" "Starting sub-test \"${stest}\""
  eval ${stest}_RC=${T_RC}
  sleep 0.2
done

for stest in ${SUB_TESTS}
do
  eval "T_PID=\${${stest}_PID}"
  wait ${T_PID}
  eval ${stest}_RC=${?}
done

cat /dev/null > recording.rlog

for proto in ${SUB_TESTS}
do
  lfile="recording.${proto}.rlog"
  if [ -e "${lfile}" ]
  then
    cat "${lfile}" >> recording.rlog
  fi
done

for stest in ${SUB_TESTS}
do
  eval "T_RC=\${${stest}_RC}"
  report_rc "${T_RC}" "Waiting for sub-test \"${stest}\" to complete"
done
