#!/s/std/bin/perl
#
# The source for this file is under cvs control in /s/www/src/cgi-www
# DO NOT edit it in /s/www/cgi-www
#
# $Id: graphs.pl,v 1.14 2012/04/03 15:03:01 ela Exp $

use strict;

# database fun
use CSL::DB_File;
use DB_File;
use Data::Dumper;

# File info/manipulation
use IO::File;
use File::stat;
use Time::localtime;
use FileHandle;

# CGI interface
use CGI qw(:standard);

BEGIN { $ENV{PATH} = '' }

my $thisfile = $ENV{'SCRIPT_FILENAME'};
($thisfile) || ($thisfile = $0);
my $thisurl = $ENV{'SCRIPT_NAME'};
($thisurl) || ($thisurl = $0);
my $grapher = "/cgi-bin/cricket/grapher.cgi";

my %possiblerange = (
    'daily' => 151200,
    'weekly' => 864000,
    'monthly' => 3628800,
    'yearly' => 41472000
);


printstart();

# Read in the config
my $ConfigFile = "/s/cricket-config/data/config.db";
my %db;
my $dbh = tie (%db, "DB_File", $ConfigFile, O_RDONLY, 0644, $DB_BTREE) or
                               error("Couldn't tie to db $ConfigFile: $!");

# Load up all the target/rrd info for each possible graph
my %targets;
foreach my $key (keys %db) {
    next unless ($key =~ /^d:(.*):.*:view$/);
    (my $target = $1) =~ s/:.*//;
    ($target) =~ s/^\///;

    my %graphs;
    foreach (split("\n", $db{$key})) {
     s/^\s+//;
     my ($key, $value) = split(": ", $_);
     $graphs{$key} = $value;
    }

    $targets{$target} = \%graphs;
}

# start going through the options provided

my $RANGE = 'daily';
$RANGE = param('range') if (param('range'));

error("Please enter a name into the above search bar.") unless (param('name') && param('hog'));

# --- Host --- #
if (param('hog') eq "host") {
    my $HOST = param("name");
    my $FQDN = (gethostbyname($HOST))[0];
    $FQDN = $HOST unless ($FQDN);
    my $group = "Unknown";

    # Find all the matching targets
    my %types;
    TARGET: foreach my $key (keys %db) {
        my $target;

        if ($key =~ /^t:\/(.*):target:($HOST|$FQDN)$/) {
		    $target = $1;
        } else {
		    next TARGET;
        }

        # If stat isn't being gathered, don't list it!
        next TARGET if $db{"d:/$target:target:$FQDN:collect"};

        my ($type, $hostgroup) = split('\/', $target);
        $group = $hostgroup if ($hostgroup ne $FQDN);

        # this is needed for afs-server-calls
        # switch between dbservers and fileservers
        ($targets{$type}) || ($type = "$type/" . (split('\/', $target))[1]);

        foreach my $graph (keys %{$targets{$type}}) {
		    (my $dslist = $targets{$type}->{$graph}) =~ s/\s+/\%2C/g;
		    $dslist =~ s/\s//g;

            $types{$type} .= a({-name=>$type}) . h2("$type: $graph") . "\n";

            $types{$type} .= p( a({-href=>"$grapher?target=/$target;ranges=d:w:m:y;view=$graph"},
                          img{-src=>"$grapher?type=png;target=/$target;dslist=$dslist;range=$possiblerange{$RANGE}", -height=>"255", -width=>"595"}) ). "\n";
        }
    }

    print h1("$FQDN (group: ", a({-href=>"$thisurl?hog=group&name=$group"}, $group), ")" ), "\n";

    if (keys %types) {

        foreach my $type (sort keys %types) {
            print hr;
            foreach my $key (sort keys %types) {
                print a({-href=>"$thisurl?hog=host&name=$HOST&range=$RANGE#$key"}, $key), " ";
            }
            print hr, "$types{$type}\n"
        }

        print hr;
        foreach my $key (sort keys %types) {
            print a({-href=>"$thisurl?hog=host&name=$HOST&range=$RANGE#$key"}, $key), " ";
        }
        print hr;
    } else {
        error("Unable to find information for host $FQDN.");
    }

# --- Group --- #

} elsif (param('hog') eq "group") {
    my $GROUP = param('name');

    print h1($GROUP), "\n";
    print "\n", hr, "\n";


    # Top Nav-Bar portion
    my $found = 0;
    KEY: foreach my $rkey (keys %db) {
        next KEY unless ($rkey =~ /^r:\/(.*)\/$GROUP$/);
        my $type = $1;
        $found++;
        print b($type), ": ";

        # Fix afs-server-calls again
        $type = "$type/$GROUP" unless ( keys %{$targets{$type}} );

        foreach my $view ( keys %{$targets{$type}} ) {
            print a({-href=>"$thisurl?hog=group&name=$GROUP&target=$type/$view"}, $view), " ";
        }
        print "<br>\n";
    }
    if ($db{"r:/$GROUP"}) {
        $found++;
        print b($GROUP), ": ";
        foreach my $view ( keys %{$targets{$GROUP}} ) {
            print a({-href=>"$thisurl?hog=group&name=$GROUP&target=$GROUP/$view"}, $view), " ";
        }
        print "<br>\n";
        
    }
    error("Unable to find information for group $GROUP.") unless $found;
    print "\n", hr, "\n";

    # Actual hosts/graphs
    if (param('target')) {

        # Fix afs-server-calls again - grab first and last arguments 1/2 or 1/3
        my @ARGS = split('\/', param('target'));
        my $check = $ARGS[0];
        my $view = $ARGS[$#ARGS];

        print h1("$check: $view"), "\n";
        TARGET: foreach my $tkey (keys %db) {
            my $host;

            if ($tkey =~ /^t:\/$check\/$GROUP\/([^:]*):target:[^:]*$/) {
                $host = $1;
            } elsif (($tkey =~ /^t:\/$GROUP\/([^:]*):target:[^:]*$/) && ($check eq $GROUP)) {
                $host = $1;
            } else {
                next TARGET;
            }

            # If host isn't current member of group, don't list it!
            next TARGET if $db{"d:/$check/$GROUP/$host:target:$host:collect"};
            next TARGET if (($db{"d:/$GROUP/$host:target:$host:collect"}) && ($check eq $GROUP));

            print h2(a({-href=>"$thisurl?hog=host&name=$host"}, $host)), "\n";

            # last afs-server-calls fix - if $check isn't there, look for +group
            my $graph;
            if ( $targets{$check}->{$view} ){
                $graph = $targets{$check}->{$view};
            } else {
                $graph = $targets{"$check/$GROUP"}->{$view};
            }
            (my $dslist = $graph) =~ s/\s+/\%2C/g;
            $dslist =~ s/\s//g;

            my $url = "$check/$GROUP";
            $url = $check if ($check eq $GROUP);

            print p( a({-href=>"$grapher?target=/$url/$host;ranges=d:w:m:y;view=$view"},
                      img{-src=>"$grapher?type=png;target=/$url/$host;dslist=$dslist;range=$possiblerange{$RANGE}", -height=>"255", -width=>"595"}) ). "\n";

        }
    }
# --- No Idea --- #

} else {
    error("Must provide a host name.");
}

printend();

###########
#
# Functions
#
###########

sub error {
    my ($error) = shift;
    ($error) || ($error = "Unknown error");

    print h2("Error: $error"), "\n  Program exiting.<br>\n";
    printend();
    exit;
}

sub printstart {
    my $thisname = "";
    $thisname = param("name") if param("name");
    my $thishog = "host";
    $thishog = param("hog") if param("hog");
    my $thisrange = "daily";
    $thisrange = param("range") if param("range");

    print header,
    start_html(-title=>"Cricket Graphs", -style=>{-src=>"/headers/csl.css"});

    print <<EOF;
<div class="navbar">
  <table border=0 width="100%">
    <tr>
      <td align=left>
        <p><form method="GET" action="$thisurl">
             <B>Search cricket for a:</B>
             <select name=hog>
               <option value=$thishog>$thishog
EOF
;

    if ($thishog eq "host") {
        print "<option value=group>group\n";
    } else {
        print "<option value=host>host\n";
    }

    print <<EOF;
             </select>
             <B>named:</B>
             <input type="text" size="30" name="name" value="$thisname">
             <B>and display the:</B>
             <select name=range>
               <option value=$thisrange>$thisrange
EOF
;
    foreach my $frequency ('daily', 'weekly', 'monthly', 'yearly') {
        print "<option value=$frequency>$frequency\n" if ($frequency ne $thisrange);
    }

    print "
             </select>
             <B>graphs.</B>\n";

    if (param('target')) {
        print "<input type=hidden name=target value=", param('target'), ">\n";
    }

    print <<EOF;
             <input type="submit" value="Search">
           </form>
      </td>
      <th>
        <div align=left>
          <a href="http://www.wisc.edu/">UW&nbsp;Madison</a><br>
          <a href="http://www.cs.wisc.edu/">Computer&nbsp;Sciences&nbsp;Department</a><br>
          <a href="http://www.cs.wisc.edu/csl/">Computer&nbsp;Systems&nbsp;Lab</a><br>
          <a href="http://www.cs.wisc.edu/cgi-bin/cricket/grapher.cgi">CSL Network Statistics</a>
        </div>
      </th>
      <td>
        <a href="http://www.cs.wisc.edu/csl">
          <img alt="[Computer Systems Lab]" align=right border=0
          src="http://www.cs.wisc.edu/pics/csl_logo.gif"></a>
      </td>
    </tr>
  </table>
</div>
EOF
;
}

sub printend {

    print <<EOF;
<table width=100% cellpadding=3>
  <tr>
    <td>
      <a href="http://www.munitions.com/~jra/cricket"><img align=left width=58 height=55 src="http://www.cs.wisc.edu/pics/cricket/cricket-sm.gif" border=0></a>
    </td><td width=15% valign=center>
      <p align=left><font size=+2>
        <a href="http://www.munitions.com/~jra/cricket">Cricket</a>
        <font size=2><br>Version 1.0.5</font>
    </td><td>
        For questions or comments about this data,
                                contact <a href="mailto:lab">Computer System Lab</a>.
    </td><td width=120 valign=center>
      <center>
      <a href="http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool"><img width=120 height=34 src="http://www.cs.wisc.edu/pics/cricket/rrdtool.gif" border=0></a>
    </td>
  </tr>
</table>
EOF
;

    print hr, "\n", small( "script last updated: ",
                                                ctime( stat($thisfile)->mtime ),
          "\n", end_html, "\n");
    exit;
}

