!******************************************************************************!
! Test timeline propagation in a pipe with file input but _pipes in the middle
! input_file -> OP -> _pipe -> OP -> output_file
!
! Arguments: keep, debug
!
! Include:   test_timeline_propagation.inc has procedures used by this test
!
! @bug       NXM-3637 Wrapped 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 tests to perform (or all)
  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_noop_usec_tll_switch      "fft_noop_usec_tll_switch.tmp"
  set fft_noop_usec_tll_qual        "fft_noop_usec_tll_qual.tmp"
  set fft_noop_usec_new_default     "fft_noop_usec_new_default.tmp"
  set fft_noop_usec_nowrap          "fft_noop_usec_nowrap.tmp"
  set fft_noop_usec_nowrap_to_tc    "fft_noop_usec_nowrap_to_tc.tmp"

  set fft_noop_tc                   "fft_noop_blue_tc.tmp"
  set fft_noop_tc_wrap              "fft_noop_blue_tc_wrap.tmp"
  set fft_noop_tc_wrap_grow         "fft_noop_blue_tc_wrap_grow.tmp"
  set fft_noop_tc_to_usec           "fft_noop_blue_tc_to_usec.tmp"

  set fft_noop_plat                 "fft_noop_plat.cdif"
  set fft_noop_plat_wrap            "fft_noop_plat_wrap.cdif"
  set fft_noop_plat_wrap_grow       "fft_noop_plat_wrap_grow.cdif"
  set fft_noop_plat_to_usec         "fft_noop_plat_to_usec.tmp"

  ! 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 "\n^reg.main.name"
  INFO "At this time, it is expected to see multiple 'This TimeLine buffer is full' warnings during this test"
  say ""

  invoke origTll nxm.sys.lib.TimeLine.getUsecPrecisionAllocDefault()
  res newTll 256
  invoke nxm.sys.lib.TimeLine.setUsecPrecisionAllocDefault(newTll)

  pipe on

    ! Tests with BLUE microsecond TIMELINE
    if micro_time then

      ! Create 2000 microsecond blue file off of NOOP with /TLL=128
      fft/id=usecwrapfftswitch ^testfile_usec_timeline _fft_blue_tll_switch nfft=^fft_size /TLL=128
      noop/TL=1/id=usecwrapswitch _fft_blue_tll_switch fft_noop_usec_tll_switch /TLL=128

      ! Create 2000 microsecond blue file off of NOOP with {TLL=128}
      fft/id=usecwrapfftqual ^testfile_usec_timeline _fft_blue_tll_qual{TLL=128} nfft=^fft_size
      noop/TL=1/id=usecwrapqual _fft_blue_tll_qual fft_noop_usec_tll_qual{TLL=128}

      ! Create 2000 microsecond blue file off of NOOP with new global usec-precision default
      fft/id=usecwrapfftnewdefault ^testfile_usec_timeline _fft_blue_new_default nfft=^fft_size
      noop/TL=1/id=usecwrapnewdefault _fft_blue_new_default fft_noop_usec_new_default

      ! Create 2000 microsecond blue file off of NOOP using TLL=-1
      fft/id=unowrapfft ^testfile_usec_timeline _fft_blue_nowrap nfft=^fft_size /TLL=-1
      noop/TL=1/id=usecnowrap _fft_blue_nowrap fft_noop_usec_nowrap /TLL=-1

      ! Create 2000 microsecond blue file off of NOOP using TLL=-1 and USEBLUETCTIMELINE=true
      fft/id=utotcfft ^testfile_usec_timeline _fft_blue_nowrap_to_tc{USEBLUETCTIMELINE=true} nfft=^fft_size /TLL=-1
      noop/TL=1/id=usectotcnowrap _fft_blue_nowrap_to_tc fft_noop_usec_nowrap_to_tc{USEBLUETCTIMELINE=true} /TLL=-1

    endif

    ! Tests with BLUE high precision TC Keywords
    if tc_time then

      ! Create 2000 TC Keyword file off of NOOP
      fft/id=tcfft testfile_tc_timeline _fft_blue_tc nfft=^fft_size
      noop/TL=1/id=tc _fft_blue_tc fft_noop_tc

      ! Create 2000 TC Keyword file off of NOOP using TLL=128
      fft/id=tcwrapfft testfile_tc_timeline _fft_blue_tc_wrap{TLL=128} nfft=^fft_size
      noop/TL=1/id=tcwrap _fft_blue_tc_wrap fft_noop_tc_wrap{TLL=128}
      
      ! Create 2000 TC Keyword file off of NOOP using TLL=-256
      fft/id=tcwrapgrowfft testfile_tc_timeline _fft_blue_tc_wrap_grow nfft=^fft_size /TLL=-256
      noop/TL=1/id=tcwrapgrow/TLL=-256 _fft_blue_tc_wrap_grow fft_noop_tc_wrap_grow

      ! Create 2000 TC Keyword file off of NOOP using TLL=-1 and USEBLUEUSECTIMELINE=true
      fft/id=tctousecfft testfile_tc_timeline _fft_blue_tc_to_usec{USEBLUEUSECTIMELINE=true,TLL=-1} nfft=^fft_size
      noop/TL=1/id=tctousec _fft_blue_tc_to_usec fft_noop_tc_to_usec{USEBLUEUSECTIMELINE=true,TLL=-1}

    endif

    ! Tests with PLATINUM high precision
    if plat_time then

      ! Create 2000 PLATINUM file off of NOOP
      fft/id=platfft testfile_plat_timeline _fft_plat nfft=^fft_size
      noop/TL=1/id=plat _fft_plat fft_noop_plat

      ! For now, the platinum tests with wrapped timelines are being skipped because 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

      ! Create 2000 PLATINUM file off of NOOP using TLL=128
      !fft/id=platwrapfft testfile_plat_timeline _fft_plat_wrap{TLL=128} nfft=^fft_size
      !noop/TL=1/id=platwrap _fft_plat_wrap fft_noop_plat_wrap{TLL=128}
      
      ! Create 2000 PLATINUM file off of NOOP using TLL=-256
      !fft/id=platwrapgrowfft testfile_plat_timeline _fft_plat_wrap_grow nfft=^fft_size /TLL=-256
      !noop/TL=1/id=platwrapgrow/TLL=-256 _fft_plat_wrap_grow fft_noop_plat_wrap_grow

      ! Create 2000 PLATINUM file off of NOOP using TLL=-1 and USEBLUEUSECTIMELINE=true
      fft/id=plattousecfft testfile_plat_timeline _fft_plat_to_usec{USEBLUEUSECTIMELINE=true,TLL=-1} nfft=^fft_size
      noop/TL=1/id=plattousec _fft_plat_to_usec fft_noop_plat_to_usec{USEBLUEUSECTIMELINE=true,TLL=-1}

    endif

  pipe off

  invoke nxm.sys.lib.TimeLine.setUsecPrecisionAllocDefault(origTll)

  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  ! check that have right number of keywords and they start at the expected value
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  ! NeXtMidas TIMELINE
  if micro_time then

    say ""
    ! NOOP FFT in pipe with /TLL=128
    info "FFT then NOOP _PIPE CHECKS -TLL Switch - 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_noop_usec_tll_switch 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"

    ! NOOP FFT in pipe with {TLL=128}
    info "FFT then NOOP _PIPE CHECKS - TLL Qualifier - 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_noop_usec_tll_qual 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"

    ! NOOP FFT in pipe with new global default
    info "FFT then NOOP _PIPE CHECKS - NEW GLOBAL DEFAULT - MICROSECOND_PRECISION"
    res t:expected {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^numWrapNewDefault,FIRST_OFFSET=^firstHackByteFFTwrapNewDefault,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_noop_usec_new_default 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 ""
    ! TLL=-1 NOOP FFT in pipe
    info "TLL=-1 FFT then NOOP _PIPE CHECKS - MICROSECOND_PRECISION"
    res t:expected {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=0.0,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_noop_usec_nowrap usecstattable
    call checkTablesSame desired usecstattable FALSE "FFT in pipe matches desired and expected behavior"

    say ""
    ! USEBLUETCTIMELINE=true,TLL=-1 NOOP FFT in pipe
    info " USEBLUETCTIMELINE=true,TLL=-1 FFT then NOOP _PIPE CHECKS - MICROSECOND_PRECISION to TC"
    res t:expected {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=1.0,LAST_OFFSET=^nFFTEntries}
    res t:desired  {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=1.0,LAST_OFFSET=^nFFTEntries}
    table usecstattable create
    %timeline_stats fft_noop_usec_nowrap_to_tc usecstattable
    call checkTablesSame desired usecstattable FALSE "FFT in pipe USEBLUETCTIMELINE=true matches desired and expected behavior"

  endif

  ! TC timeline
  if tc_time then

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

    say ""
    ! TLL=128 FFT then NOOP in pipe
    info "TLL=128 FFT then NOOP _PIPE CHECKS - BLUE_HIGH_PRECISION"
    res t:desired {FORMAT=BLUE_HIGH_PRECISION,L:NUM_ENTRIES=^num_wrap,FIRST_OFFSET=^firstHackWrapFFT,LAST_OFFSET=^nFFTEntries}
    table tcstattable create
    %timeline_stats fft_noop_tc_wrap  tcstattable
    call checkTablesSame desired tcstattable FALSE "FFT in pipe with TLL=128 matches expected behavior"

    say ""
    ! TLL=-256 FFT then NOOP in pipe
    info "TLL=-256 FFT then NOOP _PIPE 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_noop_tc_wrap_grow  tcstattable
    call checkTablesSame desired tcstattable FALSE "FFT in pipe with TLL=-256 matches expected behavior"

    say ""
    ! USEBLUEUSECTIMELINE=true,TLL=-1 FFT then NOOP in pipe
    info "USEBLUEUSECTIMELINE=true,TLL=-1 FFT then NOOP _PIPE CHECKS - BLUE_HIGH_PRECISION switching to uSec"
    res t:desired  {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackByteFFT}
    table tcstattable create
    %timeline_stats fft_noop_tc_to_usec  tcstattable
    call checkTablesSame desired tcstattable FALSE "FFT in pipe USEBLUEUSECTIMELINE=true with TLL=-1 matches expected and desired behavior"

  endif

  ! PLATINUM timeline
  if plat_time then

    say ""
    ! FFT then NOOP in pipe
    info "FFT then NOOP _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_noop_plat  platstattable
    call checkTablesSame desired platstattable FALSE "FFT in pipe matches desired and expected behavior"

    say ""
    ! TLL=128 FFT then NOOP in pipe
    info "TLL=128 FFT then NOOP _PIPE CHECKS - PLATINUM_HIGH_PRECISION"
    res t:desired {FORMAT=PLATINUM_HIGH_PRECISION,L:NUM_ENTRIES=^num_wrap,FIRST_OFFSET=^firstHackWrapPlatFFT,LAST_OFFSET=^{nFFTEntries}-1}
    table platstattable create
    !%timeline_stats fft_noop_plat_wrap  platstattable
    !call checkTablesSame desired platstattable FALSE "FFT in pipe with TLL=128 matches expected behavior"

    say ""
    ! TLL=-256 FFT then NOOP in pipe
    info "TLL=-256 FFT then NOOP _PIPE 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_noop_plat_wrap_grow  platstattable
    !call checkTablesSame desired platstattable FALSE "FFT in pipe with TLL=-256 matches expected behavior"

    say ""
    ! USEBLUEUSECTIMELINE=true,TLL=-1 FFT then NOOP in pipe
    info "USEBLUEUSECTIMELINE=true,TLL=-1 FFT then NOOP _PIPE CHECKS - PLATINUM_HIGH_PRECISION switching to uSec"
    res t:desired  {FORMAT=MICROSECOND_PRECISION,L:NUM_ENTRIES=^nFFTEntries,FIRST_OFFSET=0.0,LAST_OFFSET=^lastHackByteFFT}
    table platstattable create
    %timeline_stats fft_noop_plat_to_usec  platstattable
    call checkTablesSame desired platstattable FALSE "FFT in pipe USEBLUEUSECTIMELINE=true with TLL=-1 matches expected and desired behavior"

  endif

  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_noop_usec_tll_switch      FEXISTS THEN ERASE fft_noop_usec_tll_switch
    IF fft_noop_usec_tll_qual        FEXISTS THEN ERASE fft_noop_usec_tll_qual
    IF fft_noop_usec_tll_new_default FEXISTS THEN ERASE fft_noop_usec_tll_new_default
    IF fft_noop_usec_nowrap          FEXISTS THEN ERASE fft_noop_usec_nowrap
    IF fft_noop_usec_nowrap_to_tc    FEXISTS THEN ERASE fft_noop_usec_nowrap_to_tc
    IF fft_noop_tc                   FEXISTS THEN ERASE fft_noop_tc
    IF fft_noop_tc_wrap              FEXISTS THEN ERASE fft_noop_tc_wrap
    IF fft_noop_tc_wrap_grow         FEXISTS THEN ERASE fft_noop_tc_wrap_grow
    IF fft_noop_tc_to_usec           FEXISTS THEN ERASE fft_noop_tc_to_usec
    IF fft_noop_plat                 FEXISTS THEN ERASE fft_noop_plat
    IF fft_noop_plat_wrap            FEXISTS THEN ERASE fft_noop_plat_wrap
    IF fft_noop_plat_wrap_grow       FEXISTS THEN ERASE fft_noop_plat_wrap_grow
    IF fft_noop_plat_to_usec         FEXISTS THEN ERASE fft_noop_plat_to_usec
  else
    info "Not erasing these files: ^{testfile_usec_timeline},^{testfile_tc_timeline},^{testfile_plat_timeline}&
         ^{fft_noop_usec_tll_switch},^{fft_noop_usec_tll_qual},^{fft_noop_usec_tll_new_default},^{fft_noop_usec_nowrap},^{fft_noop_usec_nowrap_to_tc},&
         ^{fft_noop_tc},^{fft_noop_tc_wrap},^{fft_noop_tc_wrap_grow},^{fft_noop_tc_to_usec},&
         ^{fft_noop_plat},^{fft_noop_plat_wrap},^{fft_noop_plat_wrap_grow},^{fft_noop_plat_to_usec}"
  endif
return

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