!******************************************************************************!
! Test case for the following PLOT bug.
!
! Note: This test is designed to run as an overnight (or 100 hour) test
!
! @bug      2991 PLOT: Raster plot crashes
!           2457 Plot: invoking openFile(..) causes frequent NullPointerExceptions
! @since    NeXtMidas 3.7.0
! @see      related test cases: test_plot_openfile_invoke and test_plot_pipe_restarts
! @author:  Neon Ngo / Jeanette McCall
!******************************************************************************!
startmacro L:minFS[64] L:lps[16]
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE  ! for normal interactive test(s)
  switch INTERVAL    interval GET DEF=0.1              ! time in between invoking openFile(..)
  switch DURATION    duration GET DEF=360000           ! how long to run test case for (seconds)
  switch DOINVOKE    doinvoke GET DEF=TRUE  SDEF=TRUE  ! do invoke (default) or send messages
  switch REPORT      reporthours GET DEF=0.1           ! report every 6 minutes

  set secondsPerHour 3600  ! constant
  set mult_FS   0          ! used to cycle through frame sizes

  if doinvoke then
    set openfileMechanism "invoke plot.closeFile(*) and plot.openFile(.)"
  else
    set openfileMechanism "send OPENFILE info=-1 message"
  endif

  if interAct then

    calc timeInHours duration secondsPerHour /
    set instructions "This runs automatically for ^timeInHours hours (flagging any exception as FAILURE). &
                      This test is designed to run in an overnight / background test.\n\n&
                      Updating via: ^{openfileMechanism}. Running NeXtMidas ^ENV.NMVERSION"

    timer set
    pipe on
      panel/msgid=MAIN/setup/controls=gc
      gcontrol label macro "Test MACRO"
      gcontrol menu  main "Exit with Status =" "PASS,FAIL" TABLE={ItemColors={PASS="GREEN",FAIL="RED"}} /tleft

      gcontrol text   idtext    "Instructions"    instructions 24 12     /title
      gcontrol dval   dInterval "Swap interval secs " interval      0 60 0.1 /FMT="#0.###"
      gcontrol dval   dReport   "Report interval hrs" reporthours   0 10 0.1 /FMT="#0.###"

      waveform/id=testsine _wave "SF" inf sine
      plot/id=idplot /LPS=^lps

      gcontrol/id=pmon1 pipemon pmon1 _WAVE

      ! three timers, second one to stop test case
      set this.timers 3

      ! set timer to change plot
      set this.timer(0) interval

      ! set timer to exit test case
      set this.timer(1) duration

      ! set timer to report every status
      calc reportseconds reporthours secondsPerHour *
      set this.timer(2) reportseconds
    pipe off
    timer elapse

  endif
endmacro

!******************************************************************************!
! Main process message for this macro. Should be right after the ENDMACRO.
!******************************************************************************!
procedure processMessage m:msg
  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
    pipe stop

  elseif msg.name eqs "TIMER" then
    timer elapse elapsedTime
    calc timeInHours elapsedTime secondsPerHour /
    ! 2nd timer is to stop test case
    if msg.info eq 1 then
      pipe stop

    ! 3rd timer for reporting total/duration time of run
    elseif msg.info eq 2 then
      say "test case has run ^timeInHours hours :  minFS=^minFS LPS=^lps swap interval=^interval"

      if ram._wave.getpipe.outlets > 1 then
        warn "Expected only 1 reader on _wave pipe, but there are ^{ram._wave.getpipe.outlets}! after ^elapsedTime seconds."
      endif

    ! timer to switch frame size
    else
      if reg.idplot nrexists then
        assert/text="^reg.main.name: PLOT died! after ^elapsedTime seconds (~^timeInHours hours)." FAIL
        set this.timer(0) 0.0
      endif

      ! cycle through 4 frame sizes starting with minimum and ending with minimum * 4
      calc mult_FS mult_FS 1 +
      calc frame_size minFS mult_FS *
      calc mult_FS mult_FS 4 mod

      res file _wave{FS=^{frame_size}}
      !res file
      if doinvoke then
        invoke ,, reg.idplot.closeFile("*")
        invoke ,, reg.idplot.openFile(file)
      else
        sendto idplot "OPENFILE" data=file info=-1
      endif
    endif

  elseif msg.name eqs "DINTERVAL" then
    set interval msg.data
    set this.timer(0) interval

  elseif msg.name eqs "DREPORT" then
    res reporthours msg.data
    calc reportseconds reporthours secondsPerHour *
    set this.timer(2) reportseconds

  else
    say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
return

!******************************************************************************!
! If an unexpected exception is caught, mark test as failed, unless it is expected
!******************************************************************************!
procedure processException m:emsg
  if expectedException REXISTS then
    assert/text="^reg.main.name: Expected ERROR starts with: ^{expectedException}" expectedException EQSS emsg.data.message
    remove expectedException
  else
    assert/text="^reg.main.name: Caught unexpected exception ^{emsg.data}" "FALSE" isTrue
    if "Trace" SUBS ENV.DEBUG then invoke ,, emsg.data.printStackTrace()
  endif
return
