#!/bin/sh
# -*- mode:tcl -*-
#
# Copyright Tilmann Singer, 2001, expect where explicitely noted
# otherwise
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
# the next line restarts using /usr/local/bin/tclsh \
exec /usr/local/bin/tclsh "$0" "$@"

if { [catch {
    package require tclwebtest
} errmsg] } {
    puts "----
Couldn't find tclwebtest libraries. Make sure the 
tclwebtest directory is part of your \$auto_path. A 
quick way to do this is to set the TCLLIBPATH environment 
variable like this:

export TCLLIBPATH=\"\$TCLLIBPATH /path/to/your/tclwebtest\"

Note that TCLLIBPATH is a *space* seperated list of directories, unlike
your usual PATH which uses colons as seperators.
-----
Detailed error message:"

    error $errmsg
}




namespace import ::tclwebtest::*


::tclwebtest::ad_proc -private ::tclwebtest::dummy_arg_parse_proc {
    -debug:boolean
    -tidy:boolean
    {-processes 1}
    {-repeat 1}
    {-config_file {}}
    args
} {
    Used to parse the commandline switches for the executable.
} {

}

set args $argv

set show_usage_p [expr { [catch ::tclwebtest::dummy_arg_parse_proc__arg_parser errmsg] ||
                         [llength $args] < 1 }]

if { $show_usage_p } {
    puts "Usage: tclwebtest \[OPTIONS\] \[FILE|DIRECTORY\]...

Where FILE is the path to a file containing a tclwebtest script
(typically but not necessarily ending on .test). If DIRECTORY
is given then tclwebtest will execute all containing files that
end on .test.

Options:

-debug             Toggle debug output. Default off
-tidy              Toggle html check with tidy. Default off
-processes int     Number of processes to fork, needs Tclx installed. Default 1
-repeat int        Number of times each test should be repeated. Default 1
-config_file file  File to source upon startup.
"
    return -code error
}

set tclwebtest::DEBUG_LIB_P $debug_p

debug -lib "R: $repeat"

if { $processes > 1 } {
    # check if Tclx is available

    if { [catch {
        package require Tclx
    } ] } {
        error "package Tclx is not available, but it is needed to run tclwebtest with more then 1 process, because it provides the fork command. Please install the Tclx package (e.g. from here: http://sourceforge.net/projects/tclx) or run tclwebtest without the -processes option."
    }
}

if { $tidy_p } {
    set tclwebtest::TIDY 1
}

# check if the config file exists
if { [string length $config_file] > 0 } {
    if { ![file isfile $config_file] } {
        error "cannot find config file: $config_file"
    }
}

set filelist [list]

proc recurse path {
    variable filelist
    variable repeat
    if { [file isdirectory $path] } {
        # filename is a directory - process all *.test files in it
        set globbedfiles [lsort [glob -nocomplain "$path/*.test"]]

        # append them as many times as repeat tells us, same files
        # grouped together
        foreach file $globbedfiles {
            for { set i 0 } { $i < $repeat } { incr i } {
                lappend filelist $file
            }
        }
        
        # and recurse for all directories in it
        foreach dir [glob -nocomplain -types {d} "$path/*"] {
            recurse $dir
        }
        
    } else {
        # filename is a regular file
        for { set i 0 } { $i < $repeat } { incr i } {
            lappend filelist $path
        }
    }
}

foreach arg $args {
    recurse $arg
}


set error_p 0

set file_count 0
set failed_tests [list]
set kids [list]

if { $processes > 1 } {

    set child_nr -1

    for { set i 0 } { $i < $processes } { incr i } {
        set pid [fork]
        if { $pid == 0 } {
            # child
            set child_nr $i
            set ::tclwebtest::log_channel [open "out.$child_nr" w]
            break
        } else {
            # parent
            lappend kids $pid
        }
    }
} else {
    # a single process
    set child_nr 0

    # TODO
    #set ::tclwebtest::log_channel [open "out.single" w]
}

debug -lib "FILELIST: $filelist"

# TODO
set start_time [clock seconds]

for { set i 0 } { $i < [llength $filelist] } { incr i } {
    debug -lib "CHILD $child_nr IS CHECKING for $i"

    if { [expr $i % $processes] == $child_nr } {
        # it's for us - run this test
        set file_name [lindex $filelist $i]

        debug -lib "CHILD $child_nr RUNS $i"
    
        if { [::tclwebtest::run_test -config_file $config_file $file_name] } {
            lappend failed_tests $file_name
            set error_p 1
        }
    }
}

if { $child_nr == -1 || $processes == 1 } {
    foreach kid $kids {
        wait -pgroup
    }
    
    puts "DURATION: [expr [clock seconds] - $start_time]"
}


if { !$error_p } {
    exit 0
} else {
    ::tclwebtest::log "[llength $failed_tests] of [llength $filelist] tests FAILED:\n[join $failed_tests "\n"]\n"
    exit 1
}


# TODO merge logfiles in the parent process
