!******************************************************************************!
! Test Minio S3 commands
!
! Arguments: None
!
! @bug      NXM-3774 NeXtMidas should add support for minio storage
! @since    NeXtMidas 4.1.4
! @author:  Jeanette McCall
!******************************************************************************!
startmacro s:func[""]
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE  ! for normal interactive test(s)
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE  ! for defects or more obscure test case(s)

  call setDatDir
  res  preFix    "test_s3io_"
  res  urlHost   "nxmmc/"
  res  urlBucket "^{urlHost}testbucket/"
  res  urlPenny "^{urlBucket}apenny.prm"
  res  urlFmCaptureT1000 "^{urlBucket}fm_capture_t1000.prm"
  res  urlSinewave "^{urlBucket}sinewave.prm"
  res  urlRenamed "^{urlBucket}apenny_renamed.prm"
  res  urlNoopTokeywords "^{urlBucket}noop_fm_capture_t1000.prm"
  res  urlNoopToS3 "s3:^{urlBucket}noopapenny.prm"
  res  urlNoopToS3keywords "s3:^{urlBucket}noop_fm_capture_t1000.prm"
  res  urlS3NoopToS3keywords "^{urlBucket}noop_fm_capture_t1000.prm"
  res  urlFftToS3 "s3:^{urlBucket}fftsinewave.prm"
  res  urlFftToS3Keywords "s3:^{urlBucket}fft_fm_capture_t1000.prm"
  res  noopFromS3 "^{preFix}noopapenny.prm"
  res  noopFromS3Keywords "^{prefix}noop_fm_capture_t1000.prm"
  res  fftFromS3 "^{prefix}fftsinewave.prm"
  res  fftFromS3Keywords "^{prefix}fm_capture_t1000.prm"
  res  fftLocal "^{prefix}fft_sinewave_local.prm"
  res  fftLocalKeywords "^{prefix}fft_fm_capture_t1000_local.prm"

  if func NEQS "" then
    call test_^{func}
  else
    call test_s3cmds
    call test_status
    call test_noop
    call test_noop_keywords_to
    call test_noop_keywords_from
    call test_fft_to
    call test_fft_to_keywords
    call test_fft_from
    call test_fft_from_keywords
  endif

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

!******************************************************************************!
! Set the dat directory
!******************************************************************************!
procedure setDatDir
  invoke nxmMajor env.nmversion.subString(0,1)
  invoke major java.lang.Integer.valueOf(nxmMajor)
  if major GE 4 then
    invoke s:datDir           nxm.sys.test.DatLocator.getDatDirLocation()
    invoke s:datDirSlash      nxm.sys.test.DatLocator.getDatDirSlashLocation()
    invoke z:sysDatFull       nxm.sys.test.DatLocator.sysDatFull()
    invoke z:sysTestDatExists nxm.sys.test.DatLocator.sysTestDatExists()
  else
    set s:datDir           "nxm.sys.dat"
    set s:datDirSlash      "nxm/sys/dat"
    set z:sysDatFull       true
    set z:sysTestDatExists false
  endif
return

!******************************************************************************!
! Test s3 commands
!******************************************************************************!
procedure test_s3cmds

  if s3io_apenny.prm FEXISTS then
    file unprotect s3io_apenny.prm
    erase s3io_apenny.prm
  endif

  s3put ^{datDir}.apenny.prm urlPenny
  INFO "S3LS of ^urlHost"
  s3ls  urlHost
  say ""
  INFO "S3LS of ^urlBucket"
  s3ls  urlBucket
  s3get urlPenny s3io_apenny.prm
  say ""
  assert/text="^reg.main.name: S3GET retrieves item from S3PUT" s3io_apenny.prm FEXISTS
  file unprotect s3io_apenny.prm
  assert/text="^reg.main.name: S3GET file matches original" ^{datDir}.apenny.prm FEQ/D s3io_apenny.prm
  s3rename urlPenny apenny_renamed.prm
  say ""
  INFO "S3LS of ^urlBucket after rename"
  s3ls urlBucket
  s3rm urlRenamed
  say ""
  INFO "S3LS of ^urlBucket after removal"
  s3ls urlBucket

  if s3io_apenny.prm FEXISTS then
    file unprotect s3io_apenny.prm
    erase s3io_apenny.prm
  endif

return

!******************************************************************************!
! Test status
!******************************************************************************!
procedure test_status
  s3put ^{datDir}.apenny.prm urlPenny
  status "s3:^{urlPenny}"  SIZE=s3size FORM=s3form FS=s3fs
  status ^{datDir}.apenny.prm SIZE=origsize FORM=origform FS=origfs
  say ""
  assert/text="^reg.main.name: STATUS S3 SIZE matches original" origsize EQ s3size
  assert/text="^reg.main.name: STATUS S3 FORM matches original" origform EQS s3form
  assert/text="^reg.main.name: STATUS S3 FS matches original" origfs EQ s3fs
  s3rm urlPenny
  
return

!******************************************************************************!
! Test noop
!******************************************************************************!
procedure test_noop
  noop ^{datDir}.apenny.prm "^urlNoopToS3"
  noop urlNoopToS3 noopFromS3
  s3rm "^urlNoopToS3"
  assert/text="^reg.main.name: NOOP to/from S3 matches original - header" ^{datDir}.apenny.prm FEQ/H noopFromS3
  assert/text="^reg.main.name: NOOP to/from S3 matches original - keywords" ^{datDir}.apenny.prm FEQ/K noopFromS3
  assert/text="^reg.main.name: NOOP to/from S3 matches original - data" ^{datDir}.apenny.prm FEQ/D noopFromS3
  s3rm urlNoopToS3
  erase noopFromS3
return

!******************************************************************************!
! Test noop with keywords to S3
!******************************************************************************!
procedure test_noop_keywords_to
  noop ^{datDir}.fm_capture_t1000.prm "^urlNoopToS3Keywords"
  s3get urlS3NoopToS3keywords noopFromS3Keywords
  s3rm "^urlNoopToS3Keywords"
  assert/text="^reg.main.name: NOOP larger file with keywords to S3 matches original - header" ^{datDir}.fm_capture_t1000.prm FEQ/H noopFromS3Keywords
  assert/text="^reg.main.name: NOOP larger file with keywords to S3 matches original - keywords" ^{datDir}.fm_capture_t1000.prm FEQ/K noopFromS3Keywords
  assert/text="^reg.main.name: NOOP larger file with keywords to S3 matches original - data" ^{datDir}.fm_capture_t1000.prm FEQ/D noopFromS3Keywords
  s3rm urlNoopToS3Keywords
  erase noopFromS3Keywords
return

!******************************************************************************!
! Test noop with keywords from S3
!******************************************************************************!
procedure test_noop_keywords_from
  s3put ^{datDir}.fm_capture_t1000.prm "^urlNoopToKeywords"
  noop "^urlNoopToS3Keywords" noopFromS3Keywords
  s3rm "^urlNoopToS3Keywords"
  assert/text="^reg.main.name: NOOP larger file with keywords from S3 matches original - header" ^{datDir}.fm_capture_t1000.prm FEQ/H noopFromS3Keywords
  assert/text="^reg.main.name: NOOP larger file with keywords from S3 matches original - keywords" ^{datDir}.fm_capture_t1000.prm FEQ/K noopFromS3Keywords
  assert/text="^reg.main.name: NOOP larger file with keywords from S3 matches original - data" ^{datDir}.fm_capture_t1000.prm FEQ/D noopFromS3Keywords
  s3rm urlNoopToS3Keywords
  erase noopFromS3Keywords
return


!******************************************************************************!
! Test FFT to S3
!******************************************************************************!
procedure test_fft_to
  fft ^{datDir}.sinewave.prm fftLocal
  fft ^{datDir}.sinewave.prm urlFftToS3
  res fftToS3LocalCopy "^{prefix}sinewave_fft_to_s3_local_copy.prm"
  s3get urlFftToS3 fftToS3LocalCopy
  assert/text="^reg.main.name: FFT to S3 matches original - header" fftLocal FEQ/H fftToS3LocalCopy
  assert/text="^reg.main.name: FFT to S3 matches original - data" fftLocal FEQ/D fftToS3LocalCopy
  s3rm urlFftToS3
  erase fftLocal fftToS3LocalCopy
return

!******************************************************************************!
! Test FFT to S3 with file with extended header
!******************************************************************************!
procedure test_fft_to_keywords
  fft ^{datDir}.fm_capture_t1000.prm "^fftLocalKeywords"
  fft ^{datDir}.fm_capture_t1000.prm "^urlFftToS3Keywords"
  res fftToS3KeywordsLocalCopy "^{prefix}fm_capture_t1000_fft_to_s3_local_copy.prm"
  s3get urlFftToS3Keywords fftToS3KeywordsLocalCopy
  assert/text="^reg.main.name: FFT with keywords to S3 matches original with keywords - header" fftLocalKeywords FEQ/H fftToS3KeywordsLocalCopy
  assert/text="^reg.main.name: FFT with keywords to S3 matches original with keywords - data" fftLocalKeywords FEQ/D fftToS3KeywordsLocalCopy
  s3rm urlFftToS3Keywords
  erase fftLocalKeywords fftToS3KeywordsLocalCopy
return

!******************************************************************************!
! Test FFT with S3 file as input
!******************************************************************************!
procedure test_fft_from
  fft ^{datDir}.sinewave.prm fftLocal
  s3put ^{datDir}.sinewave.prm urlSinewave
  fft "s3:^urlSinewave" fftFromS3
  assert/text="^reg.main.name: FFT from S3 matches original - header" fftLocal FEQ/H fftFromS3
  assert/text="^reg.main.name: FFT from S3 matches original - data" fftLocal FEQ/D fftFromS3
  s3rm urlSinewave
  erase fftLocal fftFromS3
return

!******************************************************************************!
! Test FFT to S3
!******************************************************************************!
procedure test_fft_from_keywords
  fft ^{datDir}.fm_capture_t1000.prm fftLocalKeywords
  s3put ^{datDir}.fm_capture_t1000.prm urlFmCaptureT1000
  fft "s3:^urlFmCaptureT1000" fftFromS3Keywords
  assert/text="^reg.main.name: FFT with keywords from S3 matches original with keywords - header" fftLocalKeywords FEQ/H fftFromS3Keywords
  assert/text="^reg.main.name: FFT with keywords from S3 matches original with keywords - data" fftLocalKeywords FEQ/D fftFromS3Keywords
  s3rm urlFmCaptureT1000
  erase fftLocalKeywords fftFromS3Keywords
return

!******************************************************************************!
! Test FFT to S3 of larger file with keywords
!******************************************************************************!
procedure test_fft_and_keyword
  res fftFmCaptureT1000OriginalLocal "^{prefix}fft_fm_capture_t1000_local"
  fft ^{datDir}.fm_capture_t1000.prm fftFmCaptureT1000OriginalLocal

  fft ^{datDir}.fm_capture_t1000.prm urlFftToS3
  res fftToS3LocalCopy "^{prefox}fftfmcapturet1000_to_s3_local_copy.prm"
  s3get urlFftToS3 fftToS3LocalCopy
  assert/ext="^reg.main.name: FFT to S3 matches FFt of original" fftToS3LocalCopy FEQ/D fftFmCaptureT1000OriginalLocal AND fftToS3LocalCopy FEQ/K fftFmCaptureT1000OriginalLocal
  s3rm urlFftToS3
  erase fftToS3LocalCopy

  s3put ^{datDir}.fm_capture_t1000.prm urlFmCaptureT1000
  fft urlFmCaptureT1000 fftFromS3
  status fftFromS3
  return
  assert/text="^reg.main.name: FFT from S3 matches FFt of original" fftFromS3 FEQ/D fftFmCaptureT1000OriginalLocal AND fftFromS3 FEQ/K fftFmCaptureT1000OriginalLocal
  erase fftFromS3 fftFmCaptureT1000OriginalLocal

  keyword urlFmCaptureT1000 set name=NEWKEY value="MYNEWKEY"
  keyword urlFmCaptureT1000 get name=NEWKEY value=NEWKEYFROMS3
  assert/text="^reg.main.name: KEYWORD SET AND GET S3" NEWKEYFROMS3 eqs "MYNEWKEY"
  s3rm urlFmCaptureT1000
return
