!******************************************************************************!
! Tests the OPTION create command.
!
! Author:  Jay Hallam / Neon Ngo
!******************************************************************************!
startmacro
  switch VERBOSE verbose GET DEF=FALSE SDEF=TRUE
  switch KEEP    keep  GET DEF=FALSE SDEF=TRUE
  result z:linkSupport false
  result testOptList "1,2,3"

  if env.OSTYPE eqs "UNIX" then
    ! /link are only supported on Unix platforms
    result z:linkSupport true
    result testOptList "^{testOptList},4,5,6"
    if ^{env.NMROOT} EQS "classpath:" then
      INFO "^reg.main.name: Skipping the linking test as links cannot be created inside a jar file."
      result z:linkSupport false
    endif
  endif

  ! Create some option trees:
  !  [1] Create option [testopt1] with nxm in dir structure:
  !      testopt1 = /dirWithNxm/nxm/testopt1/
  !  [2] Create option [testopt2] with nxm in dir structure and NO trailing path separator:
  !      testopt2 = /dirWithNxm/nxm/testopt2
  !  [3] Create option [testopt3] WITHOUT nxm in initial dir structure. The "nxm" directory
  !      will be implicitly added (and created) along with the option tree name:
  !      testopt3 = /opt3ver123/nxm/testopt3
  !  -- the following option trees uses links --
  !  [4] Create option [testopt4] using link inside $NMROOT/nxm
  !      testopt4 = $NMROOT/nxm/testopt4 -> path_to_testopt4
  !  [5] Create link with nxm structure outside $NMROOT/nxm, with option name [testopt5] at
  !      the end of the link:
  !      testopt5 = /dirWithNxm/nxm/testopt5 -> path_to_testopt5
  !      nM> option/create/link="/dirWithNxm/nxm/testopt5 testopt5 path_to_testopt5
  !  [6] Create link with nxm structure outside $NMROOT/nxm, WITHOUT option name [testopt6] at
  !      the end of the link:
  !      testopt6 = /dirWithNxm/nxm/testopt6 -> path_to_testopt6
  !      nM> option/create/link="/dirWithNxm/nxm/     opt6 path_to_testopt6
  !  [7] Create back link - TBD
  !  [8] Create a different option [testopt4] to test updating of symbolic links (DR 1644) - UNIX only (but not on Solaris)
  !
  fname rootDir opt=aux area=^{aux.write} name="test_nxmopts"
  ! regular option trees
  file name opt1_path     "(^{rootDir},nxm,testopt1)"            ! [1]
  file name opt2_path     "(^{rootDir},nxm)"          "testopt2" ! [2]
  file name opt3_path     "(^{rootDir},opt3ver123)"              ! [3]
  ! option trees with links
  file name opt4_path     "(^{rootDir},opt4ver123)"              ! [4]
  file name opt4_path2    "(^{rootDir},opt4ver456)"              ! [8]
  file name opt5_path     "(^{rootDir},opt5ver123)"              ! [5]
  file name opt5_linkpath "(^{rootDir},nxm,testopt5)"            ! link path for [5]
  file name opt6_path     "(^{rootDir},opt6ver123)"              ! [6]
  file name opt6_linkpath "(^{rootDir},nxm)"                     ! link path for [6]
  ! file name opt7_path   "(^{rootDir},opt7ver123)"              ! [7] backlink - TBD

  option/create testopt1   "^{opt1_path}"            ! [1]
  option/create testopt2   "^{opt2_path}"            ! [2]
  info "Warning about option path not being valid is expected"
  option/create testopt3   "^{opt3_path}"            ! [3]
  file name opt1_verifypath "(^{rootDir},nxm,testopt1)"
  file name opt2_verifypath "(^{rootDir},nxm,testopt2)"
  file name opt3_verifypath "(^{rootDir},opt3ver123,nxm,testopt3)"
  call testOpt "Create option with nxm in dir structure."                              testopt1 opt1_verifypath ! [1]
  call testOpt "Create option with nxm in dir structure (no trailing path separator)." testopt2 opt2_verifypath ! [2]
  call testOpt "Create option WITHOUT nxm in dir structure."                           testopt3 opt3_verifypath ! [3]

  if linkSupport then
    option/create testopt4 "^{opt4_path}" /link=nxm                ! [4]
    option/create testopt5 "^{opt5_path}" /link="^{opt5_linkpath}" ! [5]
    option/create testopt6 "^{opt6_path}" /link="^{opt6_linkpath}" ! [6]
    ! option/create testopt7 "^{opt7_path}" /link=back             ! [7] backlink - TBD
    file name opt4_verifypath "(^{env.nmroot},nxm,testopt4)"
    file name opt5_verifypath "(^{opt5_linkpath})"
    file name opt6_verifypath "(^{opt6_linkpath},testopt6)"
    call testOpt "Create link inside $NMROOT/NXM."           testopt4 opt4_verifypath ! [4]
    call testOpt "Create outside NXM, with option name."     testopt5 opt5_verifypath ! [5]
    call testOpt "Create outside NXM, WITHOUT option name."  testopt6 opt6_verifypath ! [6]
    ! call testOpt "Create back link."                       testopt7 opt7_verifypath ! [7] backlink - TBD
    if env.osname neqs "SUNOS" then
      ! disabled [8] test since Solaris's ln -n option is not same as Linux's -n for --no-dereference
      option/create testopt4 "^{opt4_path2}" /link=nxm             ! [8]
      fname optpath4 opt=testopt4
      call testLink optpath4 opt4_path2
    endif
  endif

  ! debug
  if verbose then
    foreach num inlist testOptList
      option "testopt^{num}"
    endfor
    foreach num inlist testOptList
      if num eq 4 then continue ! opt4 is link inside $NMROOT/nxm
      result opt.TESTOPT^{num}
    endfor
  endif
  
  ! test adding dictionary entry at end alphabetically (Since 3.5.1 Bug_2844)
  ! (When a non-SYS option tree dictionary entry is added at the end "size" is used as an 
  ! index into the dictionary entries.  In some cases the entry array was not being resized in
  ! in time)
  path add testopt1
  update/auto name=zzzz1* opt=testopt1 support=M nargs=1+ DEF1="LABEL=ANSWER"
  update/delete zzzz1
  path remove testopt1

  ! cleanup option tree definitions in OPT table
  foreach num inlist testOptList
    option/delete TESTOPT^{num}
  endfor

  ! cleanup created option trees (actual files and dirs)
  file name opt4_unlinkpath "(^{env.nmroot},nxm)" "testopt4"
  if /KEEP then
    say "To remove the option trees created by this test, use the following:"
    if linkSupport then
      say "    $unlink ^{opt4_unlinkpath}" ! [4]
    endif
    say "    $rm -R  ^{rootDir}"           ! [1,2,3,4,5,6,7]
  else
    info "Deleting temporary option trees, use /KEEP to keep them."
    if linkSupport then
      os unlink ^{opt4_unlinkpath}  ! [4]
    endif
    invoke delcount nxm.sys.lib.BaseFile.delete(rootDir)
    if verbose then
      info "Removed ^delcount files/directories from '^{rootDir}'."
    endif
  endif

endmacro

!******************************************************************************!
! Main process message for this macro. Should be right after the ENDMACRO.
!******************************************************************************!
procedure processMessage m:msg
  say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
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

!******************************************************************************!
! Verify that the option path is same as verifyOptPath
! Check to see that commands.cnf exists for a given option
procedure testOpt s:text s:option s:verifyOptPath
  fname  optpath          opt=^option
  fname  cfgpath area=cfg opt=^option
  assert/text="[^{option}] path= ^{verifyOptPath} ." optpath eqs verifyOptPath
  assert/text="[^{option}] ^text" "^{cfgpath}/commands.cnf" FEXISTS
return

!******************************************************************************!
! Verify that the option path via link is same as explicit option path
! Check to see that commands.cnf canonical path via both routes
procedure testLink s:lname s:pname
  new java.io.File("^{lname}/cfg/commands.cnf") fobj1
  invoke S:canon1=fobj1.getCanonicalPath()
  new java.io.File("^{pname}/cfg/commands.cnf") fobj2
  invoke S:canon2=fobj2.getCanonicalPath()
  assert/text="symbolic link check " ^canon1 eqs ^canon2
return
