#!/usr/bin/perl -I/usr/lib/bs/bin -I/usr/lib/bs/uxmon
#    Big Sister network monitor
#    Copyright (C) 2000  Thomas Aeby
#
#    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., 675 Mass Ave, Cambridge, MA 02139, USA.
#

#=============================================================================
#
$main::Usage	  = "[-D level]";
#
#=============================================================================

@main::options = ( );
use common;
proginit();

use strict;
require bscgi;

use Statusmon::Statusmon;
use Statusmon::Grapher;
use Statusmon::RRDi;

$main::opt_D = 0;
my $dl = $main'dl = $main::opt_D;

my $grapher = new Statusmon::Grapher();
my $rrd = new Statusmon::RRDi();

my @colors = (
    "0000FF",
    "FF0000",
    "000000",
    "D0D020",
    "FF00FF",
    "00FFFF"
);

#   "20D020",
bscgi::mainloop( \&one_pass, "structured_bg", 300 );


sub one_pass {
    my( $skin, %cgivars ) = @_;

    my $days = $cgivars{"DAYS"};
    my $host = $cgivars{"HOST"};
    my $graph = $cgivars{"GRAPH"};
    my $start = $cgivars{"START"};
    my $mode = $cgivars{"MODE"};
    my $end = $cgivars{"END"};
    my $zoom = $cgivars{"ZOOM"};

    if( $mode ne "html" ) { $mode = "graph"; }
    unless( $zoom ) { $zoom = 100; }
     
    my @index = $grapher->get_index( $host, $graph );
    my $maingraph = {};
    for( my $i=0; $i<=$#index; $i++ ) {
	$maingraph = $grapher->read_graphdef( $index[$i]->{"fileid"} );
	last if( $maingraph->{"graph"} );
    }
    unless( $maingraph->{"graph"} ) {
	unavailable( $host, $graph );
	return;
    }

    if( $mode eq "html" ) {
	my $disp = $main::display;
	my $text = "";
	my $linkargs = "HOST=".($disp->encode($host));
	if( $graph ) { $linkargs .= "&GRAPH=".($disp->encode($graph)); }
	my $nodays = $linkargs;
	if( $days ) { $linkargs .= "&DAYS=".($disp->encode($days)); }
	my $nozoom = $linkargs;
	$linkargs .= "&ZOOM=$zoom";
	my $seq = int rand(999);

	my $maxcombine = $maingraph->{"maxcombine"};
	unless( $maxcombine ) { $maxcombine = 6; }
	if( $maxcombine >= $#colors + 1 ) { $maxcombine = $#colors + 1; }

	for( my $i=0; $i <= $#index; $i += $maxcombine ) {
	    $text .= $disp->replace_vars( $skin, {
		"HOST" => $host,
		"GRAPH" => $graph,
		"DAYS" => $days,
		"IMAGEARGS" => $linkargs."&SEQ=$seq&MODE=graph&START=$i&END=".($i+$maxcombine)
	    }, $skin->{"graph_image.proto"} );
	}
	print "Content-Type: text/html\n\n";
	print $disp->replace_vars( $skin, {
	    "HOST" => $host,
	    "GRAPH" => $graph,
	    "DAYS" => $days,
	    "ARGS" => $nodays."&MODE=html",
	    "TITLE" => ($maingraph->{"title"}).($days?" ($days days)":""),
	    "ZOOMIN" => $nozoom."&MODE=html&ZOOM=".($zoom+50),
	    "ZOOMOUT" => $nozoom."&MODE=html&ZOOM=".($zoom-50),
	    "TEXT" => $text
	}, $skin->{"graph_page.proto"} );
	exit(0);

    }

    if( $end && ($#index >= $end ) ) {
	splice( @index, $end );
    }
    if( $start ) {
	splice( @index, 0, $start );
    }

    my @args = ( "--alt-y-grid" );

    my $format = $maingraph->{"format"};
    ($format = "png") unless( ($format eq "gif") || ($format eq "png") );
    push( @args, "--imgformat", uc( $format ) );

    my( $width, $height ) = split( "x", $maingraph->{"size"} );
    ($width = 400) unless( $width );
    ($height = 100) unless( $height );
    $width = int( $width*$zoom/100 );
    $height = int( $height*$zoom/100 );
    push( @args, "--width", $width, "--height", $height );

    push( @args, "--end", time, "--start", time - $days*24*3600 );

    if( $maingraph->{"unit-label"} ) {
	push( @args, "--vertical-label", $maingraph->{"unit-label"} );
    }
    if( $maingraph->{"unit-base"} ) {
	push( @args, "--base", $maingraph->{"unit-base"} );
    }

    if( $maingraph->{"title"} ) {
	push( @args, "--title", $maingraph->{"title"} );
    }

    my( $lower, $upper ) = split( /\.\./, $maingraph->{"scale"} );
    if( ($lower ne "auto") && length($lower) ) {
	push( @args, "--lower-limit", $lower );
    }
    if( ($upper ne "auto") && length($upper) ) {
	push( @args, "--upper-limit", $upper );
    }

    for( my $i=0; $i<=$#index; $i++ ) {
	my $graph = $index[$i];
	push( @args, "DEF:v$i=".(Platform::filepath(($grapher->rrd_file( $graph )))).":a:AVERAGE" );
    }

    for( my $i=0; $i<=$#index; $i++ ) {
	my $graph = $grapher->read_graphdef( $index[$i]->{"fileid"} );

	my $legend = $graph->{"legend"};
	$legend =~ s/:/ /g;
        if ($graph->{"grtype"} =~ /stack/){
            if ($i == 0){
	       push( @args, "AREA:v$i#".($colors[$i]).($legend?":$legend":"") );
            } else {
	       push( @args, "STACK:v$i#".($colors[$i]).($legend?":$legend":"") );
            }
        } elsif ($graph->{"grtype"} =~ /area/){
	    push( @args, "AREA:v$i#".($colors[$i]).($legend?":$legend":"") );
        } else {
	    push( @args, "LINE2:v$i#".($colors[$i]).($legend?":$legend":"") );
        }
    }

    $| = 1;
    print "Pragma: no-cache\n";
    print "Cache-control: no-cache\n";
    print "Content-Type: image/$format\n\n";
    binmode STDOUT;
    if( Platforms::iswin32() ) {
	my $tmp = $main::root."/var/graph.$$";
	open( OUT, ">&STDOUT" );
	close STDOUT;
	$rrd->rrd_graph( Platform::filepath( $tmp ), @args );
	open( _GRAPH, "<$tmp" );
	binmode _GRAPH;
	print OUT <_GRAPH>;
	close _GRAPH;
	unlink $tmp;
    }
    else {
	$rrd->rrd_graph( "-", @args );
    }
}



sub unavailable {
    my( $host, $graph ) = @_;

    print "Content-Type: text/plain\n\n";
    print "Graph for host $host, ID $graph unavailable\n";
    return();
}
    

