#!/usr/local/bin/tclsh
#
# This is a small utility that dumps a pageful of statistics about your
# userfile.  It doesn't do anything besides that; it's just an information
# service. :)  To use it:
#   % tclsh eggstat <userile>
#
# Some of the stats may be incorrect for your system.  It assumes that you
# have require-x and require-p both set false.  It also counts bots when
# calculating info lines and the average number of hostmasks per user.
# Still, it's just meant to be a cute program, so enjoy.
#


if {$argc < 1} {
  puts stdout "\nUsage: eggstat <userfile>"
  puts stdout "  (gives statistics on userfile)"
  exit
}
puts stdout "\nReading $argv ..."

# User($handle)        { "password" "attr" "timestamp" "dccdir" "email"
#                        "comment" "infoline" "xtra" }
# Hostmask($handle)    { "*!*@*" "*!*@*" ... }
#
# -hostmask(s) *dccdir +email =comment :infoline

# returns 1 if loaded okay
proc loadUserFile fname {
  global User Hostmask
  set oldhandle {}
  if {[catch {set fd [open $fname r]}] != 0} { return 0 }
  while {![eof $fd]} {
    set line [string trim [gets $fd]]
    if {([string index $line 0] != "#") && ([string length $line] > 0)} {
      # not a comment, and something on the line!
      scan $line "%s" handle
      if {$handle == "-"} {
        # hostmask list (shudder!)
        set hmList [split [string range $line 3 end] ,]
        # trim the items in this list (remove whitespace)
        for {set i 0} {$i < [llength $hmList]} {incr i} {
          lappend Hostmask($oldhandle) [string trim [lindex $hmList $i]]
        }
      } elseif {$handle == "*"} {
        # dccdir
        set dccdir [string trim [string range $line 3 end]]
        set User($oldhandle) [lreplace $User($oldhandle) 3 3 $dccdir]
      } elseif {$handle == "+"} {
        # email
        set email [string trim [string range $line 3 end]]
        set User($oldhandle) [lreplace $User($oldhandle) 4 4 $email]
      } elseif {$handle == "="} {
        # comment
        set comment [string trim [string range $line 3 end]]
        set User($oldhandle) [lreplace $User($oldhandle) 5 5 $comment]
      } elseif {$handle == ":"} {
        # user info line
        set info [string trim [string range $line 3 end]]
        set User($oldhandle) [lreplace $User($oldhandle) 6 6 $info]
      } elseif {$handle == "."} {
        # xtra
        set xtra [string trim [string range $line 3 end]]
        set User($oldhandle) [lreplace $User($oldhandle) 7 7 $info]
      } else {
        # begin of new user
        scan $line "%s %s %s %s %s" handle hmask pass attr ts
        set User($handle) [list $pass $attr $ts {} {} {} {} {}]
        if {($hmask == {$placeholder$}) || ($hmask == "none")} {
          set Hostmask($handle) {}
        } {
          set Hostmask($handle) $hmask
        }
        set oldhandle $handle
      }
    }
  }
  return 1
}


if {![loadUserFile $argv]} {
  puts stderr "* Couldn't load userfile!"
  exit
}
set users [llength [array names User]]
puts stdout "\n\nStatistics:  ($users users)"
set pass 0
set email 0
set comment 0
set info 0
set hostmasks 0
set neverseen 0
set access 0; set faccess 0
set masters 0; set ops 0; set friends 0; set bots 0; set party 0; set xfer 0
foreach i [array names User] {
  if {[lindex $User($i) 0] != {nopass}} { incr pass }
  if {[lindex $User($i) 4] != {}} { incr email }
  if {[lindex $User($i) 5] != {}} { incr comment }
  if {[lindex $User($i) 6] != {}} { incr info }
  set hostmasks [expr $hostmasks + [llength $Hostmask($i)]]
  if {[lindex $User($i) 2] == 0} { incr neverseen }
  set attr [lindex $User($i) 1]
  if {[string first "m" $attr] != -1} { incr masters }
  if {[string first "o" $attr] != -1} { incr ops }
  if {[string first "f" $attr] != -1} { incr friends }
  if {[string first "b" $attr] != -1} { incr bots }
  if {[string first "p" $attr] != -1} { incr party }
  if {[string first "x" $attr] != -1} { incr xfer }
  if {([string first "m" $attr] != -1) ||
      ([string first "o" $attr] != -1) ||
      ([string first "p" $attr] != -1)} { incr access }
  if {([string first "m" $attr] != -1) ||
      ([string first "o" $attr] != -1) ||
      ([string first "x" $attr] != -1)} { incr faccess }
}
puts stdout ""
proc perfmt num {
  global users
  format "%4d (%5.1f%%)" $num [expr ($num*100.0)/$users]
}
puts stdout "[perfmt $masters] are masters  (+m)"
puts stdout "[perfmt $ops] are ops      (+o)"
puts stdout "[perfmt $friends] are friends  (+f)"
puts stdout "[perfmt $bots] are bots     (+b)"
puts stdout "[perfmt $party] can dcc-chat (+p)"
puts stdout "[perfmt $xfer] can dcc-file (+x)"
puts stdout "[perfmt $access] have some sort of party line access"
puts stdout "[perfmt $faccess] have some sort of file access"
puts stdout ""
puts stdout "[perfmt $neverseen] have never joined the channel"
puts stdout "[perfmt $info] have an info-line set"
puts stdout "[perfmt $pass] have a password set"
puts stdout "[perfmt $comment] have a comment set"
puts stdout "[perfmt $email] have an email address set"
puts stdout ""
set hmPerUser [expr ($hostmasks * 1.0)/$users]
puts stdout "average # of hostmasks per user: [format "%4.1f" $hmPerUser]"
puts stdout ""
