#!/bin/sh
# the next line restarts using wish -*-tcl-*-  \
exec tclsh "$0" ${1+"$@"}



proc puts_usage {  } {
    puts "\nSyntaxe [info script] n1 n2 ..."
    puts "n1 n2 ...: numéro des tests à lancer"
}

proc main {args} {
    global test
  
    pist_requireAll    
    
    if {![llength $args]} {
        set procsToTest [info proc test_*]
    } else {
        set procToTest [list]
        foreach n $args    {
            if {[catch {incr n 0}]} {
                puts_usage
                error "n=$n doit etre un nombre"
            } 
            if {[llength [set procName [info proc test_$n]]]} {
                lappend procsToTest $procName
            }
        }
    }
    set procsToTest [lsort $procsToTest]
    report -v args procsToTest
    report ""

    # set allTests [list]
    # foreach  p $procsToTest   {
    #     if {[regexp {[0-9]+(\.[0-9]*])?} $p match]} {
    #         lappend allTests $match
    #     }
    # }
    # set allTests [lsort $allTests]
    # 
    # if {![llength $args]} {
    #     # set tests {1 2 3}
    #     set tests {1 }
    # } else {
    #     foreach n  $args  {
    #         if {[catch {incr n 0}]} {
    #             puts stderr "n=$n doit etre un nombre"
    #             error "Syntaxe [info script] n1 n2 ..."
    #         } 
    #         lappend tests $n
    #     }
    # }
    report "test à faire : $procsToTest"
    
    foreach proc $procsToTest  {
        report "# Execution de test $proc #################"
        if [catch {$proc} msg] {
           report "\n# Message d'erreur obtenu : \n$msg\n$::errorInfo"
        } else {
           report "\n# Pas d'erreur. valeur de retour=$msg"
        }
        report "# Fin de test $proc       #################"
    } 
    
    # # report "ESSAI DU CACHE DEPUIS main"
    # # report "\[info vars ::parsarg*\] = [info vars ::parsarg*]"
    # # eval report -v [info vars ::parsarg*]
    # # report "fin de test1\n\n"
}

########################################################################
proc test_1 {} {
    
    set args {-flag1 -opt2 val2 -opt3 val3 -- argum1 argum2}
    set cmd {Parsarg_fullSpec  test1Array {
       flag1 flag
       
       opt2  "defaultVal2"
       
       o3   -
       opt3 {
              -variable VAR_OPT3
              -default "DEF3"
       }
    }}
    
    report "\n# Commande d'analyse :\n$cmd"
    report "\n# Liste à analyser"
    report -v args

    report "\n# Variables d'entrée"
    report -v test1Array
    report -v VAR_OPT3
    
    # if [catch {eval $cmd} msg] {
    #    report "\n# Message d'erreur (normal) obtenu : \n$msg"
    # } else {
    #    report "\n# Pas d'erreur. valeur de retour=$msg"
    # }
    eval $cmd
    
    report "\n# Liste apres analyse"
    report -v args 

    report "\n# Variables de sortie"
    report -v test1Array
    report -v VAR_OPT3
    

}
########################################################################
proc test_2 {} {
    # Test de switch non implémenté :
    
    set args {-flag2 argum1 argum2}
    set cmd {Parsarg_fullSpec  arga {
       flag1 flag
       
       opt2  "defaultVal2"
       
       o3   -
       opt3 {
              -variable VAR_OPT3
              -default "DEF3"
       }
    }}
    
    report "\n# Commande d'analyse :\n$cmd"
    report "\n# Liste à analyser"
    report -v args

    report "\n# Variables d'entrée"
    report -v arga
    report -v VAR_OPT3
    
    if [catch {eval $cmd} msg] {
       report "\n# Début du message d'erreur (normal) obtenu :"
       set msgLines [split $msg \n]
       # # # regexp {^[^\n]+\n[^\n]+} "$msg" firts2linesMsg
       report "[join [lrange $msgLines 0 1] \\n ]..."
    } else {
       report "\n# Pas d'erreur. valeur de retour=$msg"
    }
    # eval $cmd
    
    report "\n# Liste apres analyse"
    report -v args 

    report "\n# Variables de sortie"
    report -v arga
    report -v VAR_OPT3

}

########################################################################
proc test_3 {} {
    # Test de switch non implémenté :
    
    set args {-flag1 -opt2 val2  argum1 argum2}
    set cmd {Parsarg_fullSpec  arga {
       flag1 flag
       flag2 flag
       
       opt2  "defaultVal2"
       opt3   defaultVal3
       opt4   {{}}
       opt5   {}
    }}
    
    report "\n# Commande d'analyse :\n$cmd"
    report "\n# Liste à analyser"
    report -v args

    report "\n# Variables d'entrée"
    report -v arga
    # report -v VAR_OPT3
    
    # if [catch {eval $cmd} msg] {
    #    report "\n# Message d'erreur (normal) obtenu : \n$msg"
    # } else {
    #    report "\n# Pas d'erreur. valeur de retour=$msg"
    # }
    eval $cmd
    
    report "\n# Liste apres analyse"
    report -v args 

    report "\n# Variables de sortie"
    report -v arga
    # report -v VAR_OPT3
}

########################################################################
proc test_4 {} {
    # Test de flag explicite partiel (vérif de la valeur par défaut) :
    
    set args { argum1 argum2}
    set cmd {Parsarg_fullSpec  opt {
       flag1 {
        -type flag
        -label "The label"
       }
    }}
    
    report "\n# Commande d'analyse :\n$cmd"
    report "\n# Liste à analyser"
    report -v args

    report "\n# Variables d'entrée"
    report -v opt
    
    # if [catch {eval $cmd} msg] {
    #    report "\n# Message d'erreur (normal) obtenu : \n$msg"
    # } else {
    #    report "\n# Pas d'erreur. valeur de retour=$msg"
    # }
    eval $cmd
    
    report "\n# Liste apres analyse"
    report -v args 

    report "\n# Variables de sortie"
    report -v opt
}

########################################################################
proc test_5 {} {
    # Test type enum avec option -cache :
    
    set args { -push 1  argum1 argum2}
    set cmd {Parsarg_fullSpec -cache opt {
       push {
        -type  enum
        -values {auto 0 1}
       }
    }}
    
    report "\n# Commande d'analyse :\n$cmd"
    report "\n# Liste à analyser"
    report -v args

    report "\n# Variables d'entrée"
    report -v opt
    
    # if [catch {eval $cmd} msg] {
    #    report "\n# Message d'erreur (normal) obtenu : \n$msg"
    # } else {
    #    report "\n# Pas d'erreur. valeur de retour=$msg"
    # }
    eval $cmd
    
    # Second appel consécutif
    set args { -push 1  argum1 argum2}
    eval $cmd
    
    report "\n# Liste apres analyse"
    report -v args 

    report "\n# Variables de sortie"
    report -v opt
}


# pist_requireAll -- installe la librairie pist 
# 
# Argument : 
# 
#  - appliName : nom du tableau à initialiser (i.e gred, stead, ...).
#    Par défaut ce tableau est "pist"
# 
# Description :
# 
#  Le fonction principale de cette procédure est de mémoriser le répertoire 
#  d'installation de la librairie PIST utilisée et de la rendre utilisable
#  par une appli.
#  Si la variable d'environnement PIST_SETUP est positionnée, elle est 
#  utilisée.
#  Sinon, la librairie pist est recherchée successivement dans le répertoire 
#  courant (i.e on peut ajouter un lien "pist" dans ce répertoire courant)
#  puis dans les parents successifs. La variable d'environnement 
#  PIST_SETUP est alors positionnée pour les process fils éventuels
# 
# Hypothese :
#  
#  Chaque répertoire contenant un package pist **doit** avoir le même nom que
#  le package lui-meme :
#  Le package "Comm" doit etre dans le répertoire "Comm/", et nom par 
#  "comm/" ni "Comm-3.7/"
#  
# 
# sortie : 
# 
#  positionnement des variables suivantes (pist ou appliName si spécifié) :
#   - pist(exe) : nom absolu de cet exécutable (en vue de le re-sourcer)
#   - pist(setup)  : répertoire de l'exécutable 
#   - pist(pistsetup) et env(PIST_SETUP) : installation de PIST
#   - auto_path : insertion de pist(pistsetup) **devant** cette globale
# 
# 
proc pist_requireAll { {appliName pist} } {

global env auto_path
upvar #0 $appliName appli
   
    array set appli {
        exe         UNKNOWN
        setup       UNKNOWN
        pistsetup   UNKNOWN
    }
    
    # On mémorise le nom absolu du répertoire cette application
    cd [file dirname [info script]]
    set appli(setup) [pwd]
    
    # On mémorise le nom absolu de cette application
    set appli(exe) [file join $appli(setup) [file tail [info script] ] ]
    
    # Recherche de la librairie PIST
    if {[info exists env(PIST_SETUP)]} {
        set appli(pistsetup) $env(PIST_SETUP)
    } else {
        
        set dirsToScan [list                                            \
           $appli(setup)                                                \
           [file dir $appli(setup)]                                     \
           [file dir [file dir $appli(setup)]]                          \
           [file dir [file dir [file dir $appli(setup)]]]               \
           [file dir [file dir [file dir [file dir $appli(setup)]]]]    \
        ]
        
        # On cherche dans ce répertoire s'il y a un un plusieurs nom
        # répertoire, mais aussi lien !) commençant par pist...
        foreach dir $dirsToScan {
           
           set pistDirs [glob -nocomplain [file join $dir pist]* ]
           if {[llength $pistDirs] == 0} {
               continue
           } 
           
           # S'il existe plusieurs lib potentielle au même niveau, 
           # (pist-1.9.a et pist-1.10.a), on doit sélectionner 
           # pist-1.10 (la plus ancienne)
           # 
           foreach name [lsort -decreasing -dictionary $pistDirs] {
              set pkgIndexes [glob -nocomplain  \
                            [file join $name * pkgIndex.tcl]]
              if {[llength $pkgIndexes]} {
                 set pistSetup $name
                 break
              }
           }

           if {[info exists pistSetup]} break
         }
        
         if {![info exists pistSetup]} {
           error "Librairie PIST introuvable à partir de $appli(pistsetup) "
           exit
         }
        
         set appli(pistsetup) $pistSetup
         set env(PIST_SETUP) $appli(pistsetup)
    }
    # On ajout la librairie pist à l'auto_path
    set auto_path [concat [list $appli(pistsetup)]  $auto_path]
    
    # On demande chaque package (sous-répertoire contenant un fichier 
    # pkgIndex.tcl)
    foreach pkFile [glob -nocomplain  \
            [file join $appli(pistsetup) * pkgIndex.tcl] ]   {
        set pk [file tail [file dir $pkFile]]
        package require $pk
    }
    # parray appli
}

########################################################################
eval main $argv
# ./

