!******************************************************************************!
! Test timeline propagation in a pipe and out of a pipe that is just file-operation-file
!
! Arguments: keep, debug
!
! Include:   test_timeline_propagation.inc has procedures used by this test
!
! @bug       NXM-3637 BLUE TC timelines only writing entries since wrap
!                     Wrapped usec TIMELINE writing entries out in buffer order
!                       even when wrap is in the middle
!            NXM-3638 Timelines need to be properly propagated when in a pipe
!            NXM-3639 Nextmidas does not propagate time hacks properly - file-to-file > 128 hacks
!
! note: At this time, this test will occasionally fail due to timelinetester not always
!       generating the same # of time hacks (random jitter issue)
!
! @since     NeXtMidas 3.9.4
! @author :  Jeanette McCall

!******************************************************************************!
startmacro
  switch KEEP        keep     GET DEF=FALSE SDEF=TRUE
  switch DEBUG       debug    GET DEF=FALSE SDEF=TRUE

  global usecstattable
  global tcstattable
  global platstattable

  ! Which set of test to perform (or both)
  res micro_time true
  res tc_time true
  res plat_time true

  ! file names of starter/initial files 
  set testfile_usec_timeline   "test1000_timeline_xstart2.tmp"
  set testfile_tc_timeline     "test1000_temp_TC.tmp"
  set testfile_plat_timeline   "test1000_temp_plat.cdif"

  ! file names of files with propagated timeline keywords
  set fft_usec_pipe_propagation                  "fft_blue_usec.tmp"
  set noop_usec_pipe_propagation                 "noop_timeline1000blueUsec.tmp"
  set thin_usec_pipe_propagation                 "thin_timeline1000blueUsec.tmp"
  set fft_usec_propagation                       "fft_blue_usec_outside.tmp"
  set fft_usec_propagation_new_global_default    "fft_blue_usec_outside_new_global_default.tmp"

  set fft_tc_pipe_propagation                    "fft_blue_tc.tmp"
  set noop_tc_pipe_propagation                   "noop_timeline1000blueTC.tmp"
  set thin_tc_pipe_propagation                   "thin_timeline1000blueTC.tmp"
  set fft_tc_propagation                         "fft_blue_tc_outside.tmp"
  set fft_tc_propagation_new_global_default      "fft_blue_tc_outside_new_global_default.tmp"

  set fft_plat_pipe_propagation                  "fft_blue_plat.cdif"
  set noop_plat_pipe_propagation                 "noop_timeline1000Plat.cdif"
  set thin_plat_pipe_propagation                 "thin_timeline1000Plat.cdif"
  set fft_plat_propagation                       "fft_plat_outside.cdif"
  set fft_plat_propagation_new_global_default    "fft_plat_outside_new_global_default.cdif"

  ! make all the expected calculations and generate the initial files
  res Z:alwaysRefreshFiles false
  call setupForTimelinePropagationTest "^testfile_usec_timeline" "^testfile_tc_timeline" "^testfile_plat_timeline" alwaysRefreshFiles

  say ""
  INFO "^reg.main.name"
  INFO "At this time, it is expected to see multiple 'This TimeLine buffer is full' warnings during this test"

  !*****************************************************
  ! File -> OPERATION -> FILE propagation within a pipe
  !*****************************************************
  pipe on

    ! Tests with BLUE microsecond TIMELINE
    if micro_time then
      ! Create 2000 microsecond blue file as output of FFT
      ! Note: the fft size should evenly divide into the elements_per_timestamp
      ! this shows intermediate timestamps are ignored
      fft/id=fftusec ^testfile_usec_timeline fft_usec_pipe_propagation nfft=^fft_size

      ! Create 1000 microsecond blue file off of NOOP
      noop/TL=64/id=noopusec testfile_usec_timeline noop_usec_pipe_propagation

      thin/tl=64/id=thinusec testfile_usec_timeline thin_usec_pipe_propagation

    endif

    ! Tests with BLUE high precision TC Keywords
    if tc_time then

      ! Create 2000 TC Keyword file as output of FFT
      fft/id=ffttc testfile_tc_timeline fft_tc_pipe_propagation nfft=^fft_size

      ! Create 1000 TC Keyword file off of NOOP
      noop/TL=1/id=nooptc testfile_tc_timeline noop_tc_pipe_propagation

      thin/tl=1/id=thintc testfile_tc_timeline thin_tc_pipe_propagation

    endif

    ! Tests with BLUE PLATINUM timeline
    if plat_time then

      ! Create 2000 PLATINUM file as output of FFT
      fft/id=fftplat testfile_plat_timeline fft_plat_pipe_propagation nfft=^fft_size

      ! Create 1000 PLATINUM file off of NOOP
      noop/TL=1/id=noopplat testfile_plat_timeline noop_plat_pipe_propagation

      thin/tl=1/id=thinplat testfile_plat_timeline thin_plat_pipe_propagation

    endif

  pipe off

  !******************************************************************************
  ! File -> OPERATION -> FILE propagation outside of a pipe
  !     AND
  ! Check the resulting timeline keywords from all File -> OPERATION -> FILE propagation
  !  1) against both desired and current behavior
  !  2) TimeLine.Format
  !  3) First and last time hack
  !  4) Number of time hacks
  !  
  !******************************************************************************

  ! NeXtMidas TIMELINE
  if micro_time then

    ! do outside of pipe fft
    say ""
    info "FFT OUTSIDE PIPE - MICROSECOND_PRECISION"
    fft ^testfile_usec_timeline fft_usec_propagation nfft=^fft_size
    info "FFT OUTSIDE PIPE CHECKS - MICROSECOND_PRECISION"
    res t:expected {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^num_wrap,FIRST_OFFSET=^firstHackByteFFTwrap,LAST_OFFSET=^lastHackByteFFT}
    res t:desired  {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackByteFFT}
    table usecstattable create
    %timeline_stats fft_usec_propagation  usecstattable
    call checkTablesSame desired usecstattable TRUE "FFT outside pipe does not match desired behavior"
    call checkTablesSame expected usecstattable FALSE "FFT outside pipe matches expected behavior"

    say ""
    ! do outside of pipe fft
    info "FFT OUTSIDE PIPE WITH NEW GLOBAL DEFAULT- MICROSECOND_PRECISION"
    invoke origUsecTl nxm.sys.lib.TimeLine.getUsecPrecisionAllocDefault()
    res newUsecTl -256
    invoke nxm.sys.lib.TimeLine.setUsecPrecisionAllocDefault(newUsecTl)
    fft ^testfile_usec_timeline fft_usec_propagation_new_global_default nfft=^fft_size
    info "FFT OUTSIDE PIPE WITH NEW GLOBAL DEFAULT CHECKS - MICROSECOND_PRECISION"
    res t:desired  {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^numWrapGrow,FIRST_OFFSET=^firstHackByteFFTwrapGrow,LAST_OFFSET=^lastHackByteFFT}
    table usecstattable create
    %timeline_stats fft_usec_propagation_new_global_default  usecstattable
    call checkTablesSame desired usecstattable FALSE "FFT outside pipe with grow-to-size matches desired and expected behavior"
    invoke nxm.sys.lib.TimeLine.setUsecPrecisionAllocDefault(origUsecTl)

    say ""
    ! FFT in pipe
    info "FFT IN PIPE CHECKS - MICROSECOND_PRECISION"
    res t:expected {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^num_wrap,FIRST_OFFSET=^firstHackByteFFTwrap,LAST_OFFSET=^lastHackByteFFT}
    res t:desired  {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackByteFFT}
    table usecstattable create
    %timeline_stats fft_usec_pipe_propagation  usecstattable
    call checkTablesSame desired usecstattable TRUE "FFT in pipe does not match desired behavior"
    call checkTablesSame expected usecstattable FALSE "FFT in pipe matches expected behavior"

    say ""
    ! NOOP in pipe
    info "NOOP IN PIPE CHECKS - MICROSECOND_PRECISION"
    res t:expected {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^num_wrap,FIRST_OFFSET=^firstHackByte,LAST_OFFSET=^lastHackByte}
    res t:desired  {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^nEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackByte}
    table usecstattable create
    %timeline_stats noop_usec_pipe_propagation  usecstattable
    call checkTablesSame desired usecstattable TRUE "NOOP in pipe does not match desired behavior"
    call checkTablesSame expected usecstattable FALSE "NOOP in pipe matches expected behavior"

    say ""
    ! THIN in pipe
    info "THIN IN PIPE CHECKS - MICROSECOND_PRECISION"
    res t:expected {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^num_wrap,FIRST_OFFSET=^firstHackByte,LAST_OFFSET=^lastHackByte}
    res t:desired  {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^nEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackByte}
    table usecstattable create
    %timeline_stats thin_usec_pipe_propagation  usecstattable
    call checkTablesSame desired usecstattable TRUE "THIN in pipe does not match desired behavior"
    call checkTablesSame expected usecstattable FALSE "THIN in pipe matches expected behavior"

  endif

  ! TC timeline
  if tc_time then

    say ""
    ! do outside of pipe fft
    info "FFT OUTSIDE PIPE - BLUE_HIGH_PRECISION"
    fft testfile_tc_timeline fft_tc_propagation nfft=^fft_size
    info "FFT OUTSIDE PIPE CHECKS - BLUE_HIGH_PRECISION"
    res t:desired  {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=1.0,LAST_OFFSET=^nFFTEntries}
    table tcstattable create
    %timeline_stats fft_tc_propagation  tcstattable
    call checkTablesSame desired tcstattable FALSE "FFT outside pipe matches desired and expected behavior"

    say ""
    ! do outside of pipe fft
    info "FFT OUTSIDE PIPE WITH NEW GLOBAL DEFAULT- BLUE_HIGH_PRECISION"
    invoke origTcTl nxm.sys.lib.TimeLine.getHighPrecisionAllocDefault()
    res newTcTl -256
    invoke nxm.sys.lib.TimeLine.setHighPrecisionAllocDefault(newTcTl)
    fft testfile_tc_timeline fft_tc_propagation_new_global_default nfft=^fft_size
    info "FFT OUTSIDE PIPE WITH NEW GLOBAL DEFAULT CHECKS - BLUE_HIGH_PRECISION"
    res t:desired  {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^numWrapGrow,FIRST_OFFSET=^firstHackWrapFFTGrow,LAST_OFFSET=^nFFTEntries}
    table tcstattable create
    %timeline_stats fft_tc_propagation_new_global_default  tcstattable
    call checkTablesSame desired tcstattable FALSE "FFT outside pipe with grow-to-size matches desired and expected behavior"
    invoke nxm.sys.lib.TimeLine.setHighPrecisionAllocDefault(origTcTl)

    say ""
    ! FFT in pipe
    info "FFT IN PIPE CHECKS - BLUE_HIGH_PRECISION"
    res t:desired  {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=1.0,LAST_OFFSET=^nFFTEntries}
    table tcstattable create
    %timeline_stats fft_tc_pipe_propagation  tcstattable
    call checkTablesSame desired tcstattable FALSE "FFT in pipe matches desired and expected behavior"

    say ""
    ! NOOP in pipe
    info "NOOP IN PIPE CHECKS - BLUE_HIGH_PRECISION"
    res t:desired  {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^nEntries,FIRST_OFFSET=1.0,LAST_OFFSET=^lastHack1}
    table tcstattable create
    %timeline_stats noop_tc_pipe_propagation  tcstattable
    call checkTablesSame desired tcstattable FALSE "NOOP in pipe matches desired and expected behavior"

    say "" 
    ! THIN in pipe
    info "THIN IN PIPE CHECKS - BLUE_HIGH_PRECISION"
    res t:desired  {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^nEntries,FIRST_OFFSET=1.0,LAST_OFFSET=^lastHack1}
    table tcstattable create
    %timeline_stats thin_tc_pipe_propagation  tcstattable
    call checkTablesSame desired tcstattable FALSE "THIN in pipe matches desired and expected behavior"

  endif

  ! PLATINUM timeline
  if plat_time then

    ! For the platinum tests with wrapped timelines, the following error is being thrown:"
    ! WARN: ERROR: Invalid TimeLine entry that occurs later in the timeline, but is back in time - Offset - Current:130560.0 Previous:130560.0
    !   Time- Current:2010:03:13::02:43:50.400422096 Previous:2010:03:13::04:32:12.800702095
    ! See NXM-3698 - will need to be addressed sometime in the future

    say ""
    call printPlatWarnMsgs

    say ""
    ! do outside of pipe fft
    info "FFT OUTSIDE PIPE - PLATINUM_HIGH_PRECISION"
    fft testfile_plat_timeline fft_plat_propagation nfft=^fft_size
    info "FFT OUTSIDE PIPE CHECKS - PLATINUM_HIGH_PRECISION"
    res t:desired  {FORMAT=PLATINUM_HIGH_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^{nFFTEntries}-1}
    table platstattable create
    %timeline_stats fft_plat_propagation  platstattable
    call checkTablesSame desired platstattable FALSE "FFT outside pipe matches desired and expected behavior"

    say ""
    ! do outside of pipe fft
    info "FFT OUTSIDE PIPE WITH NEW GLOBAL DEFAULT- PLATINUM_HIGH_PRECISION"
    invoke origTcTl nxm.sys.lib.TimeLine.getHighPrecisionAllocDefault()
    res newTcTl -256
    invoke nxm.sys.lib.TimeLine.setHighPrecisionAllocDefault(newTcTl)
    !fft testfile_plat_timeline fft_plat_propagation_new_global_default nfft=^fft_size
    info "FFT OUTSIDE PIPE WITH NEW GLOBAL DEFAULT CHECKS - PLATINUM_HIGH_PRECISION"
    res t:desired  {FORMAT=PLATINUM_HIGH_PRECISION,L:NUM_ENTRIES=^numWrapGrow,FIRST_OFFSET=^firstHackWrapPlatFFTGrow,LAST_OFFSET=^{nFFTEntries}-1}
    table platstattable create
    !%timeline_stats fft_plat_propagation_new_global_default  platstattable
    !call checkTablesSame desired platstattable FALSE "FFT outside pipe with grow-to-size matches desired and expected behavior"
    invoke nxm.sys.lib.TimeLine.setHighPrecisionAllocDefault(origTcTl)

    say ""
    ! FFT in pipe
    info "FFT IN PIPE CHECKS - PLATINUM_HIGH_PRECISION"
    res t:desired  {FORMAT=PLATINUM_HIGH_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^{nFFTEntries}-1}
    table platstattable create
    %timeline_stats fft_plat_pipe_propagation  platstattable
    call checkTablesSame desired platstattable FALSE "FFT in pipe matches desired and expected behavior"

    say ""
    ! NOOP in pipe
    info "NOOP IN PIPE CHECKS - PLATINUM_HIGH_PRECISION"
    res t:desired  {FORMAT=PLATINUM_HIGH_PRECISION,L:NUM_ENTRIES=^nEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackPlat}
    table platstattable create
    %timeline_stats noop_plat_pipe_propagation  platstattable
    call checkTablesSame desired platstattable FALSE "NOOP in pipe matches desired and expected behavior"

    say "" 
    ! THIN in pipe
    info "THIN IN PIPE CHECKS - PLATINUM_HIGH_PRECISION"
    res t:desired  {FORMAT=PLATINUM_HIGH_PRECISION,L:NUM_ENTRIES=^nEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackPlat}
    table platstattable create
    %timeline_stats thin_plat_pipe_propagation  platstattable
    call checkTablesSame desired platstattable FALSE "THIN in pipe matches desired and expected behavior"

  endif

  %test_timeline_propagation_pipe/keep=^{keep}/debug=^{debug}
  %test_timeline_propagation_misc/keep=^{keep}/debug=^{debug}

  call cleanupTimeLinePropagationFiles

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
  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

!******************************************************************************!
! Cleanup files generated, unless we are keeping them for reference
!******************************************************************************!
procedure cleanupTimeLinePropagationFiles

  ! cleanup test files (if user did not added switch to keep test files)
  if keep isFalse then
    IF testfile_usec_timeline                     FEXISTS THEN ERASE testfile_usec_timeline
    IF testfile_tc_timeline                       FEXISTS THEN ERASE testfile_tc_timeline
    IF testfile_plat_timeline                     FEXISTS THEN ERASE testfile_plat_timeline

    IF fft_usec_pipe_propagation                  FEXISTS THEN ERASE fft_usec_pipe_propagation
    IF noop_usec_pipe_propagation                 FEXISTS THEN ERASE noop_usec_pipe_propagation
    IF thin_usec_pipe_propagation                 FEXISTS THEN ERASE thin_usec_pipe_propagation
    IF fft_usec_propagation                       FEXISTS THEN ERASE fft_usec_propagation
    IF fft_usec_propagation_new_global_default    FEXISTS THEN ERASE fft_usec_propagation_new_global_default

    IF fft_tc_pipe_propagation                    FEXISTS THEN ERASE fft_tc_pipe_propagation
    IF noop_tc_pipe_propagation                   FEXISTS THEN ERASE noop_tc_pipe_propagation
    IF thin_tc_pipe_propagation                   FEXISTS THEN ERASE thin_tc_pipe_propagation
    IF fft_tc_propagation                         FEXISTS THEN ERASE fft_tc_propagation
    IF fft_tc_propagation_new_global_default      FEXISTS THEN ERASE fft_tc_propagation_new_global_default

    IF fft_plat_pipe_propagation                  FEXISTS THEN ERASE fft_plat_pipe_propagation
    IF noop_plat_pipe_propagation                 FEXISTS THEN ERASE noop_plat_pipe_propagation
    IF thin_plat_pipe_propagation                 FEXISTS THEN ERASE thin_plat_pipe_propagation
    IF fft_plat_propagation                       FEXISTS THEN ERASE fft_plat_propagation
    IF fft_plat_propagation_new_global_default    FEXISTS THEN ERASE fft_plat_propagation_new_global_default
  else
    info "Not erasing these files: ^{testfile_usec_timeline},^{testfile_tc_timeline},^{testfile_plat_timeline},&
         ^{fft_usec_pipe_propagation},^{noop_usec_pipe_propagation},^{thin_usec_pipe_propagation},&
         ^{fft_usec_propagation},^{fft_usec_propagation_new_global_default},&
         ^{fft_tc_pipe_propagation},^{noop_tc_pipe_propagation},^{thin_tc_pipe_propagation},&
         ^{fft_tc_propagation},^{fft_tc_propagation_new_global_default},&
         ^{fft_plat_pipe_propagation},^{noop_plat_pipe_propagation},^{thin_plat_pipe_propagation},&
         ^{fft_plat_propagation},^{fft_plat_propagation_new_global_default}"
  endif
return

!******************************************************************************!
! Include procedures common to test_timeline_propagation test:
! setupForTimelinePropagationTest, checkTablesSame, and printPlatWarnMsgs
!******************************************************************************!
include "test_timeline_propagation.inc"
