#----------------------------------------------------------------------------
# This is part of the WWW-interface to SICS. This interface allows to 
# create batch files to be run automatically by SICS. These files are 
# stored in a special directory as files with the ending .sip by the 
# CGI-scripts or servlets creating them. Now, a system is needed which
# checks this directory regularly for new files and executes them in SICS.
# This is the purpose of the SICS-Tcl macros defined in this file.
#
# First edition: Mark Koennecke, December 1999
#----------------------------------------------------------------------------

#----------- !!!! the path where the automatic files  reside
set autofpath "/data/koenneck/tmp/auto"

#------- a variable which defines if we should operate and the current file.
set __autofile_run 0
set __auto_exe_file ""

#!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# There is a name command between the Tcl internal scan command and the
# SICS scan command. The Tcl internal has to be renamed. The following
# variable defines the name of the Tcl scan command
set tclscan stscan

#---------- do initializing things when called first time
set ret [catch [catch {autofile} msg]
if {$ret != 0} {
   VarMake autofilepath Text Mugger
   autofilepath $autofpath
   autofilepath lock
   Publish autofileexecute   User
   Publish autofile          Mugger
   Publish autostart         User
   Publish autoadd           User
   Publish autoend           User
#------- for automatic file name creation
    catch {MakeDataNumber autonumber $autofpath/autonumber.dat}
#------- check any 30 seconds
   sicscron 30 autofileexecute
} 

#--------------------------------------------------------------------------
proc autofile { {action  null} } { 
   upvar #0 __autofile_run ar

    if { [string compare $action start] == 0} {
       set ar 1
       return OK
    } elseif { [string compare $action stop] == 0 } {
       set ar 0
       return OK
    } else {
	if {$ar == 1} {
            return on
        } else {
            return off
        }
    }    
}

#--------------------------------------------------------------------------
proc autofileexecute { } {
    upvar #0  __autofile_run ar
    upvar #0  __auto_exe_file aef
    upvar #0  tclscan filescan
#--------- no operation if not activated
    if {$ar != 1} {
       return
    }
#--------- aquire a list of candidate batch files
    set tmp [autofilepath]
    set ltmp [split $tmp =]
    set tmp [lindex $ltmp 1]
    set tmp2 [string trim $tmp]/*.inp
    set ret [catch {set filelist [glob $tmp2]} msg]
    if {$ret != 0} {
      return "Nothing to do"
    }
    if { [llength $filelist] < 1 } {
       return "Nothing to do"
    }
#--------- now, in each file the second line contains the order number,
#          find the lowest one which is the next one to execute
    set minnum 999999
    set file2exe null
    foreach fil $filelist {
       set f [open $fil r]
       gets $f
       set numline [gets $f]
       set ret [catch {$filescan $numline "# %d" numi} msg]
       close $f
       if { $ret  == 0 } {
	   if { $numi < $minnum } {
              set minnum $numi
              set file2exe $fil
           }
       } else {
         ClientPut $msg
       } 
    }
#------------ having found an input file, execute it
    if { [string compare $file2exe null] != 0 } {
        set aef $file2exe
	set ret [catch {interneval $file2exe} msg]
#------ after execution rename it with a different extension
        set fil2 [file rootname $file2exe].old
        file rename -force $file2exe $fil2  
        if {$ret != 0 } {
          error $msg
        } else {
          return $msg
        }      
    }
    return "Invalid autobatch files"
}

#=========================================================================
# File management functions
#
# autostart creates a fresh file. The data is stored in a SICS runbuffer.
# autoadd adds a line to the runbuffer
# autoend writes the file to disk then.
#=========================================================================

proc autostart {} {
  catch {buf del autobuffer}
  Buf new autobuffer
} 

proc autoadd args {
  autobuffer append $args
} 

proc autoend {} {
  upvar #0 autofpath ap
  autonumber incr
  set txt [autonumber]
  set l [split $txt =]
  set txt [string trim [lindex $l 1]]
  set fil [format "$ap/auto%7.7d.inp" $txt]
  set filnum [format "# %d" $txt]
  autobuffer ins 1 $filnum
  autobuffer save $fil
  Buf del autobuffer
}

#============================================================================
# file list management 
#============================================================================

proc buildsortedlist {filar} {
  upvar #0 autofpath ap
  upvar $filar list
  set i 0
#----------- build arrays of all relevant files
    set ret [catch {set l1 [glob $ap/*.inp]}]
    if { $ret == 0 } {
       foreach fil $l1 {
          set list($i)
          incr i
          set f [open $fil r]
          set $fil(title) [gets $f]
          set txt [gets $f]
          close $f
          set ret [catch {$filescan $txt "# %d" numi} msg]
	  if { $ret == 0} {
	      set fil(no) $numi
          }else {
              set fil(no) -10
          }
       }
    }      
    set ret [catch {set l1 [glob $ap/*.old]}]
    if { $ret == 0 } {
       foreach fil $l1 {
          set list($i)
          incr i
          set f [open $fil r]
          set $fil(title) [gets $f]
          set txt [gets $f]
          close $f
          set ret [catch {$filescan $txt "# %d" numi} msg]
	  if { $ret == 0} {
	      set fil(no) $numi
          }else {
              set fil(no) -10
          }
       }
    }      
    set nfil i
#--------- now selection sort this list
    for {set i 0} { i < $nfil} {incr i} {
        set min $i
        set ff $list($min)
        for {set j [expr $i + 1]} {$j < $nfil} {incr j} {
            set ff $list($j)
            set fff $list($min)
	    if { $ff(no) < $fff(no)} {
                set min $j
            } 
        }
        set t $list($min)
        set list($min) $list($min)
        set list($i) $t
    }
}

proc autolist {} {

}

