#---------------------------------------------------------------------
# Freshmint.tcl
#
# TCL script for IRC bot eggdrop
#
# Right before a .rehash this scripts attempts to:
# 1. remove all loaded packages
# 2. remove all existing procedures
# 3. remove all existing binds
# 4. remove all minute timers
# 5. remove all second timers
#
# Upon the .rehash itself, the bot will load all bindings, packages
# and procedures from the sourced tcl files.
#
# v0: 12-Jun-2002
# v1: 15-Sep-2002
# v2: 20-Jan-2004
# + added http package to packageexempts
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Event binding and procedure
#---------------------------------------------------------------------

bind evnt - prerehash rehashpurge

proc rehashpurge { type } {

   global lastbind

   set countpack 0
   set countproc 0
   set countbind 0
   set countmint 0
   set countsect 0

   # This proc may only be called by the prerehash event binding,
   # to avoid users doing ".tcl rehashpurge blah".

   if { $lastbind != "prerehash" } {
      putlog "ERROR: Freshmint not called by prerehash event but by $lastbind bind. Aborting."
      return 0
   }

   # remove all existing packages, but keep packages in the
   # packageexempts list: removing the packages "eggdrop"
   # and "Tcl" is a bad idea :)

   lappend packageexempts eggdrop Tcl http

   foreach pack [package names] {
      # keep package "eggdrop" and "tcl"
      if {[lsearch -exact $packageexempts $pack] != -1} { continue }
      # remove package
      package forget $pack
      incr countpack
   }

   # Remove all existing bindings.
   # Bindings linked to procedure names starting with  a "*" are
   # retained. This will keep binds to eggdrops internal procedures
   # such as RAW bindings.

   foreach binding [binds] {
      # retrieve type, attr, name, hits, proc
      set bindtype [lindex $binding 0]
      set bindattr [lindex $binding 1]
      set bindname [lindex $binding 2]
      set bindhits [lindex $binding 3]
      set bindproc [lindex $binding 4]
      # do *NOT* unbind bindings to eggdrop internal procs
      if {[string index $bindproc 0] == "*"} { continue }
      # remove the binding
      unbind $bindtype $bindattr $bindname $bindproc
      incr countbind
   }

   # remove all procedures existing in current namespace (eggdrop)

   foreach command [info procs] {
      rename $command ""
      incr countproc
   }

   # kill all minute timers
   # [timers] returns a list of timers. Each element is a list of
   # three elements: timeleft command timerid.

   foreach mintimer [timers] {
      set timerid [lindex $mintimer 2]
      killtimer $timerid
      incr countmint
   }

   # kill all second timers

   foreach sectimer [utimers] {
      set timerid [lindex $sectimer 2]
      killutimer $timerid
      incr countsect
   }

   # report purging...

   putlog "Rehash: Freshmint purged $countpack packages, $countproc procedures, $countbind binds, $countmint minute timers and $countsect second timers."

}

