!
! Client part of RMIF test
!
! @author  Neon Ngo
! @bug     2017 OPENED remote clients do not timeout sometimes
! @requires NeXtMidas 2.7.3 (for killing RMIF instance)
!
! <cntrl> - The parent macro object
! <port>  - The KNOWN port of the server.
! <host>  - The KNOWN host of the server.
!
startmacro O:cntrl L:port S:host["localhost"]
  switch DEBUG   debug        GET DEF=false SDEF=true
  switch VERBOSE verbose      GET DEF=false SDEF=true
  switch STATEM  statemachine GET DEF=false SDEF=true

  set reg.cntrl cntrl
  set L:anyAvailablePort -1
  set rmifid     "RMIFCIENT"
  set L:clientAckCount 0
  invoke vercomp nxm.sys.lib.StringUtil.compareVersions("^env.nmversion","2.7.3")

  pipe on
    rmif/id=^{rmifid}/msgid=main/STATEM=^statemachine/VERBOSE=^verbose anyAvailablePort

    message FUNC=sendw ID=^{rmifid} NAME="OPEN" DATA={ID=REMOTERMIF,HP="^host:^port"}
  pipe off

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 "STOP_TEST" then
    set clientTests TEST(clientAckCount,GT,0)
    message FUNC=send ID=cntrl NAME=CLIENT_TEST INFO=0 DATA={TEXT="got ACKs from remote RMIF, count=^{clientAckCount}",TEST=^clientTests}

    rem reg.cntrl ! we put this in manually, now remove it
    pipe stop     ! sent by ctrl

  elseif msg.name eqs "START_TEST" then
    ! open ACK channel to remote
    message FUNC=send ID=REMOTERMIF NAME="ADDC" INFO=0 DATA="Q:ACK"

  elseif msg.name eqs "OPENED" then
    message FUNC=send ID=cntrl NAME=CLIENT_STARTED INFO=0 DATA={TEST=PASS}

    ! following line is only for manual standalone testing
    if cntrl isNull then message FUNC=send ID=main NAME=START_TEST info=0

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

  elseif msg.name eqs "NULL"
    ! ignore

  elseif msg.name eqs "ACK" then
    if /debugc then say "Got ACK name=^msg.name from=^msg.fid info=^msg.info data=^msg.data"

    calc L:clientAckCount clientAckCount 1 +
    if CALC(clientAckCount,10,mod) eq 1
      ! only send pass client test message to control macro for every 10th ACK
      message FUNC=send ID=cntrl NAME=CLIENT_TEST INFO=0 DATA={TEXT="CLIENT got ACK from server1. count=^clientAckCount",TEST=PASS}
    endif

    if vercomp LT 0 then
      say  "************************************************************"
      info "* Manually kill this macro right now (e.g. Ctrl+C) to complete test case on client side."
      say  "************************************************************"
    endif

    ! kill RMIF instance (for testing only) before RMIF sends out PING to SERVER and gets PONG response from SERVER
    ! this will caused pre NeXtMidas 2.7.3 RMIF server's to continue to send out ACKs packets
    message FUNC=SENDW ID=^{RMIFID} NAME=KILL_FOR_TESTING_ONLY  ! This message is for testing only, do not use in your macros.

    ! test case is done on client side
    message FUNC=send ID=cntrl NAME=CLIENT_DONE DATA={TEST=TRUE}

  elseif msg.name eqs "LINKERR"
    WARN "CLIENT: Received a LINKERR. ^msg.data"
    ! notify control macro of link error
    message FUNC=send ID=cntrl NAME=CLIENT_TEST INFO=0 DATA={TEXT="got LINKERR Message=^{msg.data.text}",TEST=FAIL}

  else
    message FUNC=send ID=cntrl NAME=CLIENT_TEST INFO=0 DATA={TEXT="got unhandled message name=^msg.name data=^msg.data",TEST=FALSE}
  endif
return
