# WARNING: This is crappy code. Some day it will be cleaned up and
# done pretty, but this was hacked out quickly, so alot of things
# that should have been done, weren't
#
package RTG::View;
  
#use strict;
use warnings;
  
use Apache::RequestRec ();
use Apache::RequestIO ();
use Apache::Const -compile => qw(OK);
use CGI;
use CGI::Carp qw(fatalsToBrowser carpout);
use DBI;


use vars qw(%table_map %table_options %snmp_modules $dbh);

my $RTG_HOME	= "/opt/rtg";
my $RTG_ETC	= "$RTG_HOME/etc";
my $RTG_MODULES	= "$RTG_ETC/rtgmodules";
my $HTTP_SRV	= "rtg.localhostdomain";
my $RTG_GIF	= "http://$HTTP_SRV/rtg.gif";
my $VIEW_URL	= "http://$HTTP_SRV/rtg";
my $RTG_PLOT	= "http://$HTTP_SRV/rtgplot.cgi";
my $db_db	= "rtg";
my $db_host	= "localhost";
my $db_user	= "snmp";
my $db_pass	= "rtgdefault";
my $REFRESH	= 300;
my $DEBUG	= 1;

sub debug($);


#
#
# because standard intface stuff isn't in a module, we add it in here
$main::table_map{'MIBII-netio'} = [ qw(ifInOctets ifOutOctets) ];
$main::table_options{'MIBII-netio'} = [ qw(factor=8 units=bits) ];
$main::table_map{'MIBII-netpkt'} = [ qw(ifInUcastPkts ifOutUcastPkts) ];
$main::table_options{'MIBII-netpkt'} = [ qw(factor=1 units=pkts/s) ];

sub handler {
	my $r = shift;
	my $q = new CGI;
	my @table_list = ();
	my %graph_list = ();
	my @row = ();
	my $router = "";
	my $sql;
	my $additional = "";
	my $graph = "";
	my $iid = "";
	my $sth;
	my $rv;
	my %start_time = ();
	my $only_graph = "";

#	$r->content_type('text/plain');
	$r->content_type('text/html');
	$r->headers_out->{'Pragma'} = "no-cache";
	$r->headers_out->{'Refresh'} = $REFRESH;


	my $url = $q->url();
	my $path = $q->path_info();

	if($path =~ /\/(.+?)\/(.*)/) { $router = $1; $additional = $2;}
	elsif($path =~ /\/(.+)/) { $router = $1; }
	else { $path = ""; }

	debug("[$router][$path][$additional]");

	# SQL Database Handle
	$dbh = DBI->connect("DBI:mysql:$db_db:host=$db_host",$db_user,$db_pass);

	unless($path ne "") {
		debug("Doing server list");

		$sql = "SELECT rid,name from router ORDER BY name";
		unless($sth = $dbh->prepare($sql)) {
			$r->log_error("Can't prepare $sql: $dbh->errstr"); 
			return Apache::DECLINED; 
		}
		unless($rv = $sth->execute) {
			$r->log_error("can't execute the query: $sth->errstr"); 
			return Apache::DECLINED; 
		}

		print "<TITLE>RTG Host List</TITLE>\n";
		print "<A HREF=\"http://rtg.sourceforge.net\"><IMG SRC=\"$RTG_GIF\" BORDER=0 ALT=\"[RTG Homepage]\"></A>\n";
		print "<H1>RTG Hosts with statistics</H1>\n";
		print "<TABLE BORDER=0 WIDTH=100%>\n";
		$column=0;
		while ( @row = $sth->fetchrow_array ) {
			if($column == 0) { print "<TR>\n"; }
			print "<TD><A HREF=\"$VIEW_URL/$row[1]\">$row[1]</A></TD>\n";
			$column++;
			if($column > 3) { print "</TR>\n"; $column = 0; }	
		}

		if($column != 0) { print "</TR>\n"; }
		
		print "</TABLE>\n";
		return Apache::OK;
	}
 
	# open up crap
	opendir(DIR,$RTG_MODULES);
	my @modfiles = grep { /.*\.pl$/ } readdir(DIR);
	closedir(DIR);

	foreach my $mod_file (@modfiles) {
		debug("Now loading module $mod_file...");
		require "$RTG_MODULES/$mod_file";
	};

	if($additional ne "") {	
		if($additional =~ /(.+)\/(.+)/) { 
			$graph = $1;
			$iid = $2;
		}
		elsif( $additional =~ /(.+)/) {
			$only_graph = $1;
			$only_graph =~ s/\///g;
		}
	} else { $graph = "" ; $iid = 0; }

	if($iid > 0) {
		debug("Doing stats here");

		debug("STAT: [$graph][$iid]");

		$end_time = time;
		
		$start_time{'Previous 24 hours'} = $end_time - 86400;
		$start_time{'Previous 7 days'} = $end_time - 604800;
		$start_time{'Previous 30 days'} = $end_time - 2592000;
		$start_time{'Previous 365 days'} = $end_time - 31536000;

		$sql = "SELECT rid FROM router WHERE name=\"$router\"";
		debug("SQL: $sql");
		unless($sth = $dbh->prepare($sql)) {
			$r->log_error("Can't prepare $sql: $dbh->errstr");
			return Apache::DECLINED;
		}
		unless($rv = $sth->execute) {
			$r->log_error("can't execute the query: $sth->errstr");
			return Apache::DECLINED;
		}

		if ( $sth->rows == 0 ) {
			print "$router is not in the database\n";
			return Apache::OK;
		}

		@rows = $sth->fetchrow_array();
		$rid = $rows[0];

		$sql = "SELECT name,description,speed from interface where id=$iid";
		debug("SQL: $sql");
		unless($sth = $dbh->prepare($sql)) {
			$r->log_error("Can't prepare $sql: $dbh->errstr");
			return Apache::DECLINED;
		}
		unless($rv = $sth->execute) {
			$r->log_error("can't execute the query: $sth->errstr");
			return Apache::DECLINED;
		}

		if(@row = $sth->fetchrow_array) { 
			$int_name = $row[0];
			$int_descr = $row[1];
			$int_speed = $row[2];
		}
		else { $int_name = "unknown"; $int_descr = "unknown"; }

		print "<TITLE>$router Historial view ($int_name)</TITLE>\n";
		print "<A HREF=\"http://rtg.sourceforge.net\"><IMG SRC=\"$RTG_GIF\" BORDER=0 ALT=\"[RTG Homepage]\"></A>\n";
#		print "<HR>\n";
		print "<DL>\n";
		print "<DD> Host: $router\n";
		print "<DD> Name: $int_name\n";
		print "<DD> Descr: $int_descr\n";
		print "<DD> OIDs: ".join(" ",@{$main::table_map{$graph}})."\n";
		if($int_speed > 0) {
			print "<DD> Speed: $int_speed\n";
		}
		print "</DL>\n";
		print "<HR>\n";
		print "Statistics last updated on ".localtime($end_time)."\n";
		print "<HR>\n";

		if($int_descr eq "") { $int_descr = $int_name; }
		
		foreach $graph_type (sort { $start_time{$b} <=> $start_time{$a} } keys %start_time) {
			
			$t=1;
			$graph_line = "$RTG_PLOT?";

			$beg_time = $start_time{$graph_type};

			
			
			debug("Creating $graph for int $iid - full view - $graph_type"); 
			foreach $table (@{$main::table_map{$graph}}) {
				$graph_line .= "t".$t."=".$table."_$rid&";
				$t++;
			}
			$graph_line .= "begin=$beg_time&";
			$graph_line .= "end=$end_time&";
			$graph_line .= "iid=$iid&";

			foreach $options (@{$main::table_options{$graph}}) {
				$graph_line .= "$options&";
			}

			# remote the trailing &
			chop($graph_line);

			# change % sign to valid url format
			$graph_line =~ s/\%/\%25/g;
			# change any spaces to valid url format
			$graph_line =~ s/\s/\%20/g;

	
			print "$graph_type\n";
			print "<BR>\n";
			print "<IMG SRC=\"$graph_line\" BORDER=0 ALIGN=TOP VSPACE=10 ALT=\"$int_name\">\n";
			print "<BR CLEAR=ALL>";
			print "</TD>\n";
			debug("GRAPH: $graph_line");
			debug("GRAPH: $int_descr");

		}	

		return Apache::OK;
	} 

	debug("Doing machine daily view");

	if (!$dbh) {
		print "Could not connect to database ($db_db) on $db_host.\n";
		print "Check configuration.\n";
		exit(-1);
	}

	$sql = "SELECT rid FROM router WHERE name=\"$router\"";
	debug("SQL: $sql");
	unless($sth = $dbh->prepare($sql)) {
		$r->log_error("Can't prepare $sql: $dbh->errstr");
		return Apache::DECLINED;
	}
	unless($rv = $sth->execute) {
		$r->log_error("can't execute the query: $sth->errstr");
		return Apache::DECLINED;
	}
	if ( $sth->rows == 0 ) {
		print "$router is not in the database\n";
		return Apache::OK;
	}
	else {
		@row = $sth->fetchrow_array();
		$rid = $row[0];
		$sql = "SHOW TABLES LIKE '%\\_$rid'";
		debug("SQL: $sql");
		unless($sth = $dbh->prepare($sql)) {
			$r->log_error( "Can't prepare $sql: $dbh->errstr");
			return Apache::DECLINED;
		}
		unless($rv = $sth->execute) {
			$r->log_error("can't execute the query: $sth->errstr");
			return Apache::DECLINED;
		}

		while(@row = $sth->fetchrow_array) {
			push(@table_list,$row[0]);
		}
	}


	# find out what graphs that we need to make given the tables that 
	# exist in the database
	foreach $graph (keys %main::table_map) { 
debug("checking: [$graph][$main::table_map{$graph}][$only_graph]");
		next if($only_graph ne "" & $only_graph ne $graph);

		foreach $table (@{$main::table_map{$graph}}) { 
			if(grep { /$table/ } @table_list ) {
				$graph_list{$graph} = ();
			}
		}
	}

	#
	# get list of interfaces for the graph
	foreach $graph (keys %graph_list) { 
		$sql = "SELECT DISTINCT id from $main::table_map{$graph}[0]_$rid";
		debug("SQL: $sql");
		unless($sth = $dbh->prepare($sql)) {
			$r->log_error( "Can't prepare $sql: $dbh->errstr");
			return Apache::DECLINED;
		}
		unless($rv = $sth->execute) {
			$r->log_error("can't execute the query: $sth->errstr");
			return Apache::DECLINED;
		}

		@temp_array = ();

		while(@row = $sth->fetchrow_array) {
			push(@{$graph_list{$graph}},$row[0]);
		}

	}

	# get the time, and set the end for back 24 hours
	my $end_time = time;
	my $beg_time = $end_time - 86400;

	#
	# graph each stat, for each inteface on each stat
	#
	$column = 0;

	print "<TITLE>RTG Stats for $router</TITLE>\n";
	print "<A HREF=\"http://rtg.sourceforge.net\"><IMG SRC=\"$RTG_GIF\" BORDER=0 ALT=\"[RTG Homepage]\"></A>\n";
	print "<H2>RTG Statistics for $router (last 24 hours)</H2>\n";
	print "<HR>\n";
	print "Statistics last updated on ".localtime($end_time)."\n";
	print "<HR>\n";
	print "<TABLE BORDER=0 WIDTH=100%>\n";
	foreach $graph (sort {uc($a) cmp uc($b) } keys %graph_list) { 
		foreach $iid (@{$graph_list{$graph}}) { 

			# get interface description
			$sql = "SELECT name,description,status from interface where id=$iid";
			debug("SQL: $sql");
			unless($sth = $dbh->prepare($sql)) {
				$r->log_error( "Can't prepare $sql: $dbh->errstr");
				return Apache::DECLINED;
			}
			unless($rv = $sth->execute) {
				$r->log_error("can't execute the query: $sth->errstr");
				return Apache::DECLINED;
			}

			if(@row = $sth->fetchrow_array) { 
				$int_name = $row[0];
				$int_descr = $row[1];
				$int_status = $row[2];
			}
			else { $int_name = "unknown"; $int_descr = "unknown"; }

			if($int_status eq "inactive") { next; }

			if($column == 0 ) { print "<TR>\n"; }
			print "<TD>\n";

			$graph_line = "$RTG_PLOT?";
			$t=1;
			debug("Creating $graph for int $iid"); 
			foreach $table (@{$main::table_map{$graph}}) {
				$graph_line .= "t".$t."=".$table."_$rid&";
				$t++;
			}
			$graph_line .= "begin=$beg_time&";
			$graph_line .= "end=$end_time&";
			$graph_line .= "iid=$iid&";

			foreach $options (@{$main::table_options{$graph}}) {
				$graph_line .= "$options&";
			}

			$graph_line .= "xplot=400&";
			$graph_line .= "yplot=100";
			# remove the trailing &
			# chop($graph_line);
			# change % sign to valid url format
			$graph_line =~ s/\%/\%25/g;
			# change any spaces to valid url format
			$graph_line =~ s/\s/\%20/g;

			print "$int_name ($int_descr)\n";
			print "<BR>\n";
			print "<A HREF=\"$VIEW_URL/$router/$graph/$iid\">\n";
			print "<IMG SRC=\"$graph_line\" BORDER=0 ALIGN=TOP VSPACE=10 ALT=\"$int_name\">\n";
			print "</A>\n";
			print "<BR CLEAR=ALL>";
			print "</TD>\n";
			debug("GRAPH: $graph_line");
			debug("GRAPH: $int_descr");
			$column++;
			if($column == 2) { print "</TR>\n"; $column = 0; }
		}
	}

	if($column != 0) { print "</TR>\n"; }
	print "</TABLE>\n";

      return Apache::OK;
}

sub debug($) {
	$debug_line = shift;
	#print "<p>$debug_line\n" if $DEBUG;
	$debug_line =~ s/\>/\&\#62\;/g;
	$debug_line =~ s/\</\&\#60\;/g;
	print "<!-- DEBUG: $debug_line -->\n" if $DEBUG;
}

1;
