# Random commands for sbnc
# Copyright (C) 2011 Khobbits
#
# 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.

###############################################################################
############## You shouldn't NEED to edit anything in this file. ##############
### I don't recall where but the showusers command I stole from somewhere. ####
###############################################################################

internalbind command kh:com

proc kh:com {client parameters} {
	set command [lindex $parameters 0]
	if {[string equal -nocase $command "help"]} {
		if {[getbncuser $client admin]} {
			bncaddcommand "showusers" "KHAdmin" "Shows the currently connected user counts" "Syntax: showusers"
			bncaddcommand "msimul" "KHAdmin" "Makes all clients do the command" "Syntax: msimul <commands to perform>\nThis command does runs a simul command for all users at once.  Support for: \$me \$ip \$user \$1-5 vars"
			bncaddcommand "lastused" "KHAdmin" "Shows a list of last used times" "Syntax: lastused \[days\]\nIf you provide a number of days it wont show users who have logged in the last \[days\]"
			bncaddcommand "usingvhost" "KHAdmin" "Shows a list of users using a specific vhost (ip)" "Syntax: usingvhost <ip>"
			bncaddcommand "traffic" "KHAdmin" "Shows user traffic" "Syntax: traffic <wildcard match text>"
    }
    else {
      bncaddcommand "traffic" "KHUser" "Shows user traffic"    
    } 
    bncaddcommand "uptime" "KHUser" "Shows current connection length"		
	}
	if {[getbncuser $client admin]} {
    if {[string equal -nocase $command "msimul"]} { khz:msimul $client $parameters }		
		if {[string equal -nocase $command "showusers"]} { khz:showusers $client $parameters }
		if {[string equal -nocase $command "lastused"]} { khz:lastused $client $parameters }
		if {[string equal -nocase $command "usingvhost"]} { khz:usingvhost $client $parameters }
  } 
  if {[string equal -nocase $command "uptime"]} { bncreply "User uptime: [duration [getbncuser $client uptime]]"; haltoutput; }
	if {[string equal -nocase $command "traffic"]} { khz:traffic $client $parameters } 
}

proc khz:msimul {client arg} {
	foreach user [bncuserlist] {
		setctx $user
		set msg [string map [list \$me [getcurrentnick] \$ip [getbncuser $user vhost] \$user $user \$1 [lindex [split $arg] 1] \$2 [lindex [split $arg] 2] \$3 [lindex [split $arg] 3] \$4 [lindex [split $arg] 4] \$5 [lindex [split $arg] 5]] $arg]
		puthelp "[join [lrange $msg 1 end]]"
	}
	putmainlog "$client used msimul: $arg"
	haltoutput
	return
}


proc khz:showusers {client parameters} {
    variable ctx [getctx]
    variable online 0 connected 0 suspended 0 unknown 0
    array set networks {}

    foreach user [bncuserlist] {
      setctx $user
      if { [getbncuser $user hasclient] } {
        incr online
      }

      if { [getbncuser $user hasserver] } {
        incr connected
        set un [getisupport NETWORK]
        if { $un eq "" } {
          incr unknown
          continue
        }
        if { ![info exists networks($un)] } {
          set networks($un) 1
        } else {
          incr networks($un)
        }
      }
      if { ([getbncuser $user lock] eq "1") } {
        incr suspended
      }
    }

    setctx $ctx
    bncreply "Total current user count: [llength [bncuserlist]], logged on: $online, connected to IRC: $connected, suspended: $suspended."
    set result [list]
    foreach name [array names networks] {
      lappend result "$networks($name) on $name"
    }
    if { $unknown ne "0" } {
      lappend result "$unknown on unknown networks"
    }
    bncreply [join $result {, }]
    haltoutput
  return
}

proc khz:lastused {client parameters} {
	set y [lindex $parameters 1]
	if {[catch {expr int($y)}]} { set y -1 }
	foreach x [bncuserlist] {
		if { [getbncuser $x seen] != 0 } {
			if { [expr ( [clock seconds] - [getbncuser $x seen] ) /86400.0 ] > $y } {
					bncreply "$x last logged in [duration [expr [clock seconds] - [getbncuser $x seen]]]days ago"
			}
		} else {
			bncreply "$x has never logged in"
		}
	}
	haltoutput
  return
}

proc khz:usingvhost {client parameters} {
	if {[lindex $parameters 1] == ""} {
		bncreply "Syntax: usingvhost <ip>"
		haltouput
		return
	}
	bncreply "Using vhost '[lindex $parameters 1]':"
	foreach x [bncuserlist] {
		if { [getbncuser $x vhost] == [lindex $parameters 1] } {
			bncreply $x
		}
	}
    haltoutput
  return
}

proc khz:traffic {client parameters} {
	if {[getbncuser $client admin] && [lindex $parameters 1] != ""} {
	  set match [lindex $parameters 1]	
	} else {
    set match $client
  }
  bncreply "Traffic Stats for users matching ${match}:"
  set in 0; set out 0; set server 0; set client 0;
  
  foreach client [bncuserlist] { 
    if {[string match $match $client]} { 
      incr in [trafficstats $client server in]
      incr out [trafficstats $client server out]
      incr in [trafficstats $client client in]
      incr out [trafficstats $client client out]
      incr server [trafficstats $client server in]
      incr server [trafficstats $client server out]
      incr client [trafficstats $client client in]
      incr client [trafficstats $client client out]
    }
  }
  bncreply "Total in: [bytes $in] :: Total out: [bytes $out]" 
  bcnreply "Client<->BNC Total: [bytes $client] :: Server<->BNC Total: [bytes $server]"  
}

proc bytes { text } {
	for {set fsize [expr {double($text)}]; set pos 0} {$fsize >= 1024} {set fsize [expr {$fsize / 1024}]} {
		incr pos;
	}
	set a [lindex [list "B" "KiB" "MiB" "GiB" "TiB" "PiB" "EiB" "ZiB" "YiB"] $pos];
	set fsize [format "%.2f%s" $fsize $a];
	return "$fsize"
}
