# -*- Tcl -*-

package prefer latest

package require nx
package require nx::test


## for now, we do not have scripted shells for Windows environments
## without a bash-like shell, so ...

if {$tcl_platform(platform) eq "windows"} {
  return
}

#
# When the compiler flags modify the console output, come of the shell
# tests below will fail. One should introduce more detailed test
# conditions like in tcl-test to deal with the more precisely. For the
# time being, we skip here the full test when nsf was compiled with
# memcount activated.
#
if {$::nsf::config(memcount) == 1} {
  return
}


nx::test case nxsh {
  set rootDir [file join {*}[lrange [file split [file normalize [info script]]] 0 end-2]]
  set nxsh [file join $rootDir nxsh]

  set run {puts $argc-[join $argv -]}
  
  ? [list file exists $nxsh] 1
  ? [list file executable $nxsh] 1
   ## stdin is in interactive mode (just a smoke test)
  ? [list exec $nxsh << "$run; exit"] "% 0-"
  ## stdin is ignored
  proc getFirstLine {cmd} {
    catch [list uplevel 1 $cmd] res opts
    set lines [split $res \n]
    return [string trim [lindex $lines 0]]
  }
  ? [list getFirstLine [list exec $nxsh NXSCRIPT.tcl << "$run; exit"]] \
      "couldn't read file \"NXSCRIPT.tcl\": no such file or directory"
  ## noninteractive mode (-c)
  ? [list exec $nxsh -c "$run" NXSCRIPT.tcl] \
      "1-NXSCRIPT.tcl"
  ? [list exec $nxsh -c << $run] "0-"
  ? [list exec $nxsh -c $run a b c] "3-a-b-c"

  set tmpfile [file join [::nsf::tmpdir] [pid]]
  ? [list getFirstLine [list exec $nxsh $tmpfile]] "couldn't read file \"$tmpfile\": no such file or directory"
  ? [list getFirstLine [list exec $nxsh $tmpfile a b c]] "couldn't read file \"$tmpfile\": no such file or directory"

  set ch [open $tmpfile w+]
  ? [list file exists $tmpfile] 1
  ? [list file writable $tmpfile] 1
  puts $ch $run
  catch {close $ch}
  ? [list exec $nxsh $tmpfile] "0-"
  ? [list exec $nxsh $tmpfile -c "yyy" a b c] "5--c-yyy-a-b-c"

  file delete -force $tmpfile

  # exit and exit codes

  ? [list exec [info nameofexecutable] << "exit 0"] ""
  ? [list exec [info nameofexecutable] << "exit 1"] "child process exited abnormally"

  ? [list exec [info nameofexecutable] << "package req nx;exit 0"] ""
  ? [list exec [info nameofexecutable] << "package req nx;exit 1"] "child process exited abnormally"

  ? [list exec -ignorestderr [info nameofexecutable] << "package req nx;nx::Object new {exit 0}"] ""
  ? [list exec -ignorestderr [info nameofexecutable] << "package req nx;nx::Object new {exit 1}"] "child process exited abnormally"

  ? [list exec $nxsh -c "exit 0"] ""
  ? [list exec $nxsh -c "exit 1"] "child process exited abnormally"
  ? [list exec $nxsh -c "exit 2"] "child process exited abnormally"
  ? [list exec $nxsh -c "exit 5"] "child process exited abnormally"

  ? [list catch [list exec $nxsh -c "exit 5"] ::res ::opts] "1"
  ? {set ::res} "child process exited abnormally"
  ? {lindex [dict get $::opts -errorcode] end} "5"
  unset ::res; unset ::opts

  ? [list exec $nxsh -c << "exit 0"] ""
  ? [list exec $nxsh -c << "exit 1"] "child process exited abnormally"
  ? [list exec $nxsh -c << "catch {exit 1}"] "child process exited abnormally"
  ? [list exec $nxsh -c << "catch {nx::Object eval {exit 1}}"] "child process exited abnormally"

  # just 8.6 or newer
  if {[info command yield] eq ""} return
  ? [list exec $nxsh -c << [list nx::Object eval {try { exit 6 } \
                                                      on break {} {;} \
                                                      on return {} {;} \
                                                      on error {} {;} \
                                                      finally {puts finalized}}]] "child process exited abnormally"
  ? [list exec $nxsh -c << [list nx::Object eval {try { error } \
                                                      on break {} {;} \
                                                      on return {} {;} \
                                                      on error {} {;} \
                                                      finally {puts finalized}}]] "finalized"

  ## avoid pollution of global namespace
  ## set tclsh [info nameofexecutable]
  ## set gvars1 [exec $tclsh << {puts [info vars]}]
  ## set gvars2 [exec $nxsh -c << {puts [info vars]}]
  ## ? [list expr [list [lsort $gvars1] eq [lsort $gvars2]]] 1
}


puts exec=[info nameofexecutable]
# Local variables:
#    mode: tcl
#    tcl-indent-level: 2
#    indent-tabs-mode: nil
# End:
