#!/usr/local/bin/perl
#
#  Purpose:
#  flowmonitor_archive_restore is a tool for restoring archived 
#  FlowMonitors that may have gotten lost in the shuffle.
#
#  Description:
#  Simply recreates the graphs as of the latest date and time that the
#  FlowMonitor was updated. For Groups it will recreate the graphs from
#  the latest update time from all of the Group components.
#
#  Controlling Parameters (specified in FlowViewer_Configuration.pm):
#  Name                 Description
#  -----------------------------------------------------------------------
#  rrd_area             Color of the area underneath the graph
#  rrd_line             Color of the line at the top of the graphed area
#  rrd_width            Width of the graph
#  rrd_height           Height of the graph
#  rrd_font             Color of the font used in the graphs
#  rrd_back             Image background color
#  rrd_canvas           Color of the background of the actual graph
#  rrd_grid             Color of the minor grid lines
#  rrd_mgrid            Color of the major grid lines
#  rrd_frame            Color of the graph frame
#  rrd_shadea           Color for the top and left border
#  rrd_shadeb           Color for the right and bottom border
#  rrd_thick            Thickness of the line at the top of the graph
#  rrd_lower_limit      Bottom of the y-axis
#  rrd_slope_mode       "--slope-mode" will round off tops of graph  
#  rrd_vrule_color      Color of the line that indicates when the filter was changed
#
#  Modification history:
#  Author       Date            Vers.   Description
#  -----------------------------------------------------------------------
#  J. Loiacono  05/08/2012      4.0     Original version
#
#$Author$
#$Date$
#$Header$
#
###########################################################################
#
#               BEGIN EXECUTABLE STATEMENTS
#
 
use FlowViewer_Configuration;
use FlowViewer_Utilities;
use lib $cgi_bin_directory;

if (!-e "$monitor_directory") {
        $mkdir_command = "mkdir $monitor_directory";
        system($mkdir_command);
        chmod $html_dir_perms, $monitor_directory;
}

# Load the colors 
     
$colors_file = "$cgi_bin_directory/FlowGrapher_Colors"; 
     
open (COLORS,"<$colors_file") || die "Can't open colors file; $colors_file\n"; 
while (<COLORS>) { 
        chop;    
        ($red,$green,$blue,$color_1,$color_2) = split(/\s+/); 
        $color_name = $color_1; 
        if ($color_2 ne "") { $color_name = $color_1 . " " . $color_2; } 
        $R = &dec2hex($red);   if (length($R) < 2) { $R = "0" . $R; }  
        $G = &dec2hex($green); if (length($G) < 2) { $G = "0" . $G; }  
        $B = &dec2hex($blue);  if (length($B) < 2) { $B = "0" . $B; }  
        $hex_colors{$color_name} =  $R . $G . $B; 
}    
$hex_colors{"standard"} = $rrd_area; 
sub dec2hex($) { return sprintf("%lx", $_[0]) } 

if ($time_zone eq "") { 
        open(DATE,"date 2>&1|");   
        while (<DATE>) {  
                ($d_tz,$m_tz,$dt_tz,$t_tz,$time_zone,$y_tz) = split(/\s+/,$_);  
        }        
}  

while ($filter_file = <$filter_directory/*>) {

	($directory,$monitor) = $filter_file =~ m/(.*\/)(.*)$/;
	($monitor,$extension) = split(/\./,$monitor);

	if ($extension ne "archive") { next; }

	$num_monitors++;

        # Load information from filter file for graph creation
      
	$monitor_type = "";
	@component_links = ();
	$vrule_1 = "";
	$vrule_2 = "";
	$vrule_3 = "";
	$hrule = "";
	$alert_threshold = 0;

        open (FILTER,"<$filter_file"); 
        while (<FILTER>) { 
                chop;    
                $key = substr($_,0,8); 

                if ($key eq " input: ") { 

                        ($input,$field,$field_value) = split(/: /); 

			if (($field eq "monitor_type")  || ($field eq "tracking_type"))  { $monitor_type  = $field_value; }
			if (($field eq "monitor_label") || ($field eq "tracking_label")) { $monitor_label = $field_value; }
			if ($field eq "general_comment") { $general_comment = $field_value; }
			if ($field eq "alert_threshold") { $alert_threshold = $field_value; }

                        if ($field eq "revision") { 

                                ($notate_graphs,$revision_date,$revision_comment) = split(/\|/,$field_value);  
                                $revision_date_out = epoch_to_date($revision_date,"LOCAL"); 
                                $revision_date_out =~ s/:/\\:/g;

                                if ($notate_graphs eq "Y") {   
					if (($vrule_1 ne "") && ($vrule_2 ne "") && ($vrule_3 ne "")) {
						$vrule_1 = $vrule_2;
						$vrule_2 = $vrule_3;
                                                $vrule_3 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
					}
                                        if ($vrule_1 eq "") { 
                                                $vrule_1 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                next; }  
                                        elsif ($vrule_2 eq "") { 
                                                $vrule_2 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                next; }  
                                        elsif ($vrule_3 eq "") { 
                                                $vrule_3 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                next;  
                                        } 
                                }       

				if ($alert_threshold > 0) {
					$hrule = "    HRULE:$alert_threshold#$rrd_hrule_color";
				}
			}
                }
	}
        close (FILTER);

	if ($monitor_type eq "Group") {

		print "creating graphs for Group: $monitor starting at latest of components:\n";

		$group_last_update = 0;

                open (FILTER,"<$filter_file"); 
                while (<FILTER>) { 
                        chop;    
                        $key = substr($_,0,8); 
                        if ($key eq " input: ") { 
				next;
			} else {
			        ($component_position,$component_label,$component_color) = split(/\^/);
				$component_file = $component_label; 
				$component_file =~ s/^\s+//; 
				$component_file =~ s/\s+$//; 
				$component_file =~ s/\&/-/g; 
				$component_file =~ s/\//-/g; 
				$component_file =~ s/\(/-/g; 
				$component_file =~ s/\)/-/g; 
				$component_file =~ s/\./-/g; 
				$component_file =~ s/\s+/_/g; 
				$component_file =~ tr/[A-Z]/[a-z]/;
				$component_html  = $monitor_short ."/". $component_file ."/index.html";
				push (@component_links,$component_html);

				$component_rrd  = $rrdtool_directory ."/". $component_file .".archive";
				if (!-e $component_rrd) { $component_rrd  = $rrdtool_directory ."/". $component_file .".rrd"; }

				if (-e $component_rrd) {
		                        open (INFO,">$work_directory/Archive_info");
		                        $rrd_info_command = "$rrdtool_bin_directory/rrdtool info $component_rrd > $work_directory/Archive_info";
		                        system($rrd_info_command);
		                        open (INFO,"<$work_directory/Archive_info");
		                        while (<INFO>) {
		                                chop;
		                                $lead = substr($_,0,11);
		                                if ($lead eq "last_update") {
		                                        ($lead,$last_update) = split(/ = /);
        						$component_time_out = epoch_to_date($last_update,"LOCAL"); 
							print "                component: $component_label last updated: $component_time_out\n";
							if ($last_update > $group_last_update) { $group_last_update = $last_update; }
		                                }
		                        }
		                        close (INFO);
				}
			}
		}

		$last_update = $group_last_update;

	} else {

                $rrdtool_file = "$rrdtool_directory/$monitor" . ".archive";  

                open (INFO,">$work_directory/Archive_info");
                $rrd_info_command = "$rrdtool_bin_directory/rrdtool info $rrdtool_file > $work_directory/Archive_info";
                system($rrd_info_command);
                open (INFO,"<$work_directory/Archive_info");
                while (<INFO>) {
                        chop;
                        $lead = substr($_,0,11);
                        if ($lead eq "last_update") {
                                ($lead,$last_update) = split(/ = /);
                        }
                }
                close (INFO);

        	$current_time_out = epoch_to_date($last_update,"LOCAL"); 
		print "creating graphs for Indiv: $monitor  starting at: $current_time_out\n";
	}

	$html_directory = $monitor_directory ."/". $monitor;

        $end_rrd = $last_update + 7200;
        $current_time_out = epoch_to_date($last_update,"LOCAL"); 
        $current_time_rrd = $current_time_out . " $time_zone"; 
        $current_time_rrd =~ s/:/\\:/g; 

	# Create each of the four graphs for this monitor
	
	foreach $graph_type ("Daily", "Weekly", "Monthly", "Yearly", "Three Years") {
	
		$x_grid  = "";

		if ($graph_type eq "Daily") {
			$start_rrd = $end_rrd - 86400;
                        $line_peak = "",
			$sample = "     Data collected over 5 minute periods          Graph Last Updated\\: $current_time_rrd";
			$rrd_title = "\"Last 24 Hours\"";
			if ($labels_in_titles) { $rrd_title = "\"$monitor_label\: Last 24 Hours\""; }
			$graph_file = "$monitor_directory/$monitor/daily.png"; }
		elsif ($graph_type eq "Weekly") {
			$start_rrd = $end_rrd - (7*86400);
                        $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
			$sample = "     Data averaged over 30 minute periods          Graph Last Updated\\: $current_time_rrd";
			$rrd_title = "\"Last 7 Days\"";
			if ($labels_in_titles) { $rrd_title = "\"$monitor_label\: Last 7 Days\""; }
			$graph_file = "$monitor_directory/$monitor/weekly.png"; }
		elsif ($graph_type eq "Monthly") {
			$start_rrd = $end_rrd - (28*86400);
                        $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
			$sample = "     Data averaged over 2 hour periods             Graph Last Updated\\: $current_time_rrd";
			$rrd_title = "\"Last 4 Weeks\"";
			if ($labels_in_titles) { $rrd_title = "\"$monitor_label\: Last 4 Weeks\""; }
			$graph_file = "$monitor_directory/$monitor/monthly.png"; }
		elsif ($graph_type eq "Yearly") {
			$start_rrd = $end_rrd - (365*86400);
                        $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
			$sample = "     Data averaged over 24 hour periods            Graph Last Updated\\: $current_time_rrd";
			$rrd_title = "\"Last 12 Months\"";
			if ($labels_in_titles) { $rrd_title = "\"$monitor_label\: Last 12 Months\""; }
			$graph_file = "$monitor_directory/$monitor/yearly.png";
		}
		elsif ($graph_type eq "Three Years") {
			$start_rrd = $end_rrd - (3*365*86400);
                        $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
			$sample = "     Data averaged over 24 hour periods            Graph Last Updated\\: $current_time_rrd";
			$rrd_title = "\"Last Three Years\"";
			if ($labels_in_titles) { $rrd_title = "\"$monitor_label\: Last Three Years\""; }
			$x_grid = "--x-grid MONTH:1:YEAR:1:MONTH:2:2800000:%b";
			$graph_file = "$monitor_directory/$monitor/threeyears.png";
		}

		if ($monitor_type eq "Group") {

			$DEF_parameters  = "";
			$AREA_parameters = "";
			@components = ();

        		open (GROUP,"<$filter_file"); 
        		@group_lines = <GROUP>; 
        		close (GROUP); 
     
        		foreach $group_line (@group_lines) { 
                		if ($group_line =~ / input:/) { next; }
                		else { push (@components,$group_line); } 
        		}

			$num_components = 0;
			$first_below = 1;
			$group_last_update = 0;

        		foreach $component (@components) { 

			        $num_components++;
			        chop $component;
			        ($component_position,$component_label,$component_color) = split(/\^/,$component);
			 
				$component_file = $component_label; 
				$component_file =~ s/^\s+//; 
				$component_file =~ s/\s+$//; 
				$component_file =~ s/\&/-/g; 
				$component_file =~ s/\//-/g; 
				$component_file =~ s/\(/-/g; 
				$component_file =~ s/\)/-/g; 
				$component_file =~ s/\./-/g; 
				$component_file =~ s/\s+/_/g; 
				$component_file =~ tr/[A-Z]/[a-z]/;
				$component_rrd  = $rrdtool_directory ."/". $component_file .".rrd";

				$component_archive  = $rrdtool_directory ."/". $component_file .".archive";
				if (-e $component_archive) { $component_rrd = $component_archive; }
			 
			        $DEF_parameters  .= "DEF:flowbits$num_components=$component_rrd:flowbits:AVERAGE ";
			        $AREA_parameters .= "COMMENT:\"     \" ";
			 
			        if ($component_position < 200) {
			                $AREA_parameters .= "AREA:flowbits$num_components#$hex_colors{$component_color}:\"$component_label\\n\":STACK ";
			        } elsif (($component_position >= 200) && ($first_below)) {
			                $DEF_parameters .= "CDEF:flowbits_below$num_components=flowbits$num_components,-1,* ";
			                $AREA_parameters .= "AREA:flowbits_below$num_components#$hex_colors{$component_color}:\"$component_label\\n\" ";
			                $first_below = 0;
			        } else {
			                $DEF_parameters .= "CDEF:flowbits_below$num_components=flowbits$num_components,-1,* ";
			                $AREA_parameters .= "AREA:flowbits_below$num_components#$hex_colors{$component_color}:\"$component_label\\n\":STACK ";
			        }
			}
			
			@graph_parameters =  
		        ('--title',"$rrd_title",  
		        '--start',$start_rrd,  
		        '--end',$end_rrd,  
		        '--width',$rrd_width,  
		        '--height',$rrd_height,  
		        '--interlace',  
		        '--vertical-label',"\"Bits per Second\"",  
		        $x_grid,
		        $rrd_slope_mode,  
		        "--color=FONT#$rrd_font",  
		        "--color=BACK#$rrd_back",  
		        "--color=CANVAS#$rrd_canvas",  
		        "--color=GRID#$rrd_grid",  
		        "--color=MGRID#$rrd_mgrid",  
		        "--color=FRAME#$rrd_frame",  
		        "--color=SHADEA#$rrd_frame",  
		        "--color=SHADEB#$rrd_frame",  
		        '--lower-limit',$rrd_lower_limit,  
		        $DEF_parameters, 
                        "COMMENT:\"$sample   \"",
                        "COMMENT:\" \\n\"",
		        $AREA_parameters,
                        "COMMENT:\" \\n\"",
                        $vrule_1,
                        $vrule_2,
                        $vrule_3);

		} else {

                        @graph_parameters =
                        ('--title',"$rrd_title",
                        '--start',$start_rrd,
                        '--end',$end_rrd,
                        '--width',$rrd_width,
                        '--height',$rrd_height,
                        '--interlace',
                        '--vertical-label',"\"Bits per Second\"",
		        $x_grid,
                        $rrd_slope_mode,
                        "--color=FONT#$rrd_font",
                        "--color=BACK#$rrd_back",
                        "--color=CANVAS#$rrd_canvas",
                        "--color=GRID#$rrd_grid",
                        "--color=MGRID#$rrd_mgrid",
                        "--color=FRAME#$rrd_frame",
                        "--color=SHADEA#$rrd_frame",
                        "--color=SHADEB#$rrd_frame",
                        '--lower-limit',$rrd_lower_limit,
                        "DEF:flowbits=$rrdtool_file:flowbits:AVERAGE",
                        "DEF:flowpeak=$rrdtool_file:flowbits:MAX",
                        'VDEF:flowbitsmax=flowbits,MAXIMUM',
                        'VDEF:flowbitsavg=flowbits,AVERAGE',
                        'VDEF:flowbitsmin=flowbits,MINIMUM',
                        'VDEF:flowbitspct=flowbits,95,PERCENT',
                        "AREA:flowbits#$rrd_area",
                        "LINE$rrd_thick:flowbits#$rrd_line:",
                        "COMMENT:\"$sample   \"",
                        "COMMENT:\" \\n\"",
                        "COMMENT:\"             Maximum    \"",
                        "GPRINT:flowbitsmax:\"%6.2lf %Sbps\"",
                        "COMMENT:\"             \"",
			$line_peak,
                        "COMMENT:\" \\n\"",
                        "COMMENT:\"             95thPct    \"",
                        "GPRINT:flowbitspct:\"%6.2lf %Sbps \"",
                        "COMMENT:\" \\n\"",
                        "COMMENT:\"             Average    \"",
                        "GPRINT:flowbitsavg:\"%6.2lf %Sbps \"",
                        "COMMENT:\" \\n\"",
                        "COMMENT:\"             Minimum    \"",
                        "GPRINT:flowbitsmin:\"%6.2lf %Sbps \"",
                        "COMMENT:\"                        [List Values]\\n\"",
                        "COMMENT:\" \\n\"",
                        $vrule_1,
                        $vrule_2,
                        $vrule_3,
			$hrule);
		}
 
                $rrdgraph_command = "$rrdtool_bin_directory/rrdtool graph " . "$graph_file " . "@graph_parameters " . ">/dev/null";
		if ($debug_monitor eq "Y") { print DEBUG "\n\n$rrdgraph_command\n\n"; }

                system($rrdgraph_command);

		chmod $graph_file_perms, $graph_file;
	}
}
