!
! Server (receiver) side of RMIF Remote reuse test
!
! <cntrl>   - The parent control macro object
! <port>    - The KNOWN port of the server.  Client uses any available port.
! <msgCnt>  - The number of messages the client (sender) will send out to verify
!             against the number of SET messages received. Note, that, since we
!             are expecting this test case to cause packet drops, the expected
!             received messages should be (msgCnt - number of packets dropped).
!
! @bug     1051
! @author  Neon Ngo
! @since   NeXtMidas 2.5.1
!------------------------------------------------------------------------------!
startmacro O:cntrl L:port L:msgCnt[150] D:timeout
  switch TRACE   trace        GET DEF=false SDEF=true
  switch DEBUG   debug        GET DEF=false SDEF=true
  switch VERBOSE verbose      GET DEF=false SDEF=true
  switch STATEM  statemachine GET DEF=false SDEF=true

  invoke headless nxm.sys.lib.Shell.isHeadless()
  if statemachine and headless then
    info "SKIPPING ^reg.main.name because this test intermittently fails with /STATEM in HEADLESS mode."
  else
    set reg.cntrl cntrl   ! control macro

    set wait     5        ! Number of extra seconds to wait for extra messages
    set L:count  0        ! Total SET messages received
    set passFail "PASS"   ! Overall status
    set normalStop false  ! If this macro was stopped normally (internally)
    calc smallerTimeout timeout wait 1.5 * -

    pipe on
      ! startup RMIF server (to receive messages from client)
      rmif/id=RECEIVER/msgid=MAIN/STATEM=^statemachine/VERBOSE=^verbose ^port

      message FUNC=send ID=cntrl NAME=SERVER_STARTED INFO=0 DATA={TEST=PASS}

      ! 2014-03-10: using two timers for this test:
      !  1st timer to give additional time to wait for msgs after test completes
      !  2nd timer for a smaller timeout then timeout, as test occasionally does not get or account
      !    for all lost packets (another issue), but we want still want this test to complete so that
      !    it can detect if it is within desired tolerance and allow the test to pass, otherwise the
      !    test fails b/c of timeout detected in parent control macro.
      set this.timers 2
      set this.timer(1) smallerTimeout
    pipe off
  endif
endmacro

!******************************************************************************!
procedure processMessage m:msg
  if debug then
    say "^reg.main.name: Got message name=^msg.name fid=^msg.fid info=^msg.info data=^msg.data"
  endif

  if msg.name eqs "START_TEST" then
    ! do nothing, waiting for client to send packets

  elseif msg.name eqs "STOP_TEST" then  ! msg sent by control macro
    ! check if we received correct # of messages
    calc/type=f recvMsgPercentage count msgCnt / 100 *
    set passFail TEST(count eq msgCnt OR recvMsgPercentage ge 90) ! give tolerance of 90% of packets
    if count neq msgCnt then
       ! TODO: investigate the occasional missing packets when sending 3000+ msgs (even after accounting for the dropped packets? threading issue?)"
       calc L:missingMsgCount msgCnt count -
       warn "received ^count of ^msgCnt (^{recvMsgPercentage}%) of expected messages. missing ^missingMsgCount"
    endif
    message FUNC=send ID=cntrl NAME=SERVER_TEST &
            DATA={TEXT="received ^{count} of ^{msgCnt} messages (^{recvMsgPercentage}%)",TEST=^passFail}
    rem reg.cntrl  ! we put this in manually, now remove it
    pipe stop

  elseif msg.name eqs "DECREASE_MSG_COUNT" then
    ! got a dropped packet, so decrease the number of packets expected
    calc L:msgCnt msgCnt msg.data -
    if count EQ msgCnt then
      ! We should be done now, but wait a few seconds to see if extra messages are sent...
      set this.timer(0) wait
    endif

  elseif msg.name eqs "SET" then
    calc L:count count 1 +
    if count GT msgCnt then
      ! received more messages than expected, mark overall test as failed
      set passFail FAIL
    elseif count EQ msgCnt then
      ! We should be done now, but wait a few seconds to see if extra messages are sent...
      set this.timer(0) wait
    endif

  elseif msg.name eqs "OPEN" then
    ! ignore
  elseif msg.name eqss "CLOSE" then
    ! ignore CLOSE and CLOSED messages
  elseif msg.name eqs "NULL" then
    ! ignore

  elseif msg.name eqs "TIMER" then
    set this.timer(0) 0.0
    set this.timer(1) 0.0
    ! done waiting for any extra messages
    message FUNC=send ID=cntrl NAME=SERVER_DONE DATA={TEST=^passFail}

  elseif msg.name eqs "LINKERR" then
    if msg.data.text NEQSS "PKTLOST" then
      ! notify control macro of link error as a failed test
      message FUNC=send ID=cntrl NAME=SERVER_TEST INFO=0 &
              DATA={TEXT="got unexpected LINKERR data=^msg.data",TEST=FAIL}
    endif
  else
    ! notify control macro of unknown message as a failed test
    message FUNC=send ID=cntrl NAME=SERVER_TEST INFO=0 &
            DATA={TEXT="got unhandled message name=^msg.name data=^msg.data",TEST=FAIL}
  endif
return
