#!/usr/local/bin/perl -w
#
# $Source: /home/cur/djb1/develop/logtools/RCS/count-to-gnuplot,v $
#
# $Id: count-to-gnuplot,v 1.3 1995/03/07 12:06:52 djb1 Exp $
#
# Convert a summary by count into gnuplot files
#
# USAGE: count-to-gnuplot [config options] [--scheme=schemes]
#                         [--sum=accesses | bytes] output file [count file]
#
# (C) Copyright 1994,1995 Dave Beckett <D.J.Beckett@ukc.ac.uk>
# University of Kent at Canterbury
#
# This program is free software; you may distribute under the terms of
# either the GNU General Public License or the Artistic License, as
# specified in the README file.
#

require 'option_utils.pl';

$verbose;


sub parse_local_options {
  local(*args)=@_;
  local($usage)=0;
  local($scheme)='';
  local($sum)='';

  local(@newargs)=();
  while(defined($_=shift(@args))) {
    if (/^--scheme=(.+)$/) {
      $scheme=$1;
    } elsif (/^--sum=(.+)$/) {
      $sum=$1;
      if ($sum ne 'accesses' && $sum ne 'bytes') {
	warn "$prog_name: Illegal summary type '$sum' - choose accesses or bytes\n";
	$usage=1;
      }
    } else {
      push(@newargs, $_);
      last if /^--$/ || !/^--/;
    }
  }
  @args=(@newargs, @args);
  return ($usage,$scheme,$sum);
}


sub count2gnuplot {
  local($output_file,$count_file,$sum,$allschemes,@schemes)=@_;

  if ($verbose>0) {
    warn "$prog_name: Processing count file '$count_file'\n";
    warn "$prog_name: with all schemes seen in data\n" if $allschemes;
    warn "$prog_name: with schemes @schemes\n" if !$allschemes;
    warn "$prog_name: to '${output_file}-...'\n";
  }

  if (!open (SUMCOUNT, $count_file)) {
    warn "$prog_name: Could not open '$count_file' - $!\n";
    return;
  }

  local($firstdate)='';     # From 'period ... ...'
  local($lastdate)='';      # "
  local(@fields)=();        # From 'fields ...'
  local($nofields)=0;
  local($datacount)=0;
  local(%schemes_seen)=();
  while(<SUMCOUNT>) {
    chop;
    next if /^#/;
    if (/^period\s+(\S+)\s+(\S+)/) {
      $firstdate=$1 if !$firstdate || $1 lt $firstdate;
      $lastdate=$2 if !$lastdate || $2 gt $lastdate;
      next;
    }
    if (/^fields\s+(.*)$/) {
      @fields=split(/\s+/,$1);
      $nofields=scalar(@fields);
      warn "Found fields=@fields\n" if $debug>1;
      next;
    }

    if (/^sort-field\s+(.*)$/) {
      warn "$prog_name: Found sort field '$1' in summary by count - I'm lost\n";
      return;
    }
    
    if (/^data\s+(.*)$/) {
      local($info)=$1;

      warn "data:'$info'\n" if $debug>5;

      if (!$nofields) {
	warn "$prog_name: Cannot process -- no 'fields' line seen before data\n";
	return;
      }

      # HACK - relies on fixed output of sum-count field order
      local($this_scheme,$this_scheme_value,$this_count,$this_byte)=split(/ /,$info);
      $schemes_seen{$this_scheme}=1;
      next if !grep(/^$this_scheme$/,@schemes) && !$allschemes;

      local($value)=($sum eq 'accesses') ? $this_count : $this_byte;
      eval "\$${this_scheme}_data\{'$this_scheme_value'\}='$value'";

      $datacount++;

      next;
    }

    warn "$prog_name:$count_file:$.:Ignoring line: '$_'\n";
  }
  close(SUMCOUNT);

  if (!$datacount) {
    warn "$prog_name: No schemes matched those given (@schemes)\n";
    warn "$prog_name: Valid schemes seen in data: ".join(' ',keys %schemes_seen)."\n";
    return;
  }

  @schemes=keys %schemes_seen if $allschemes;

  foreach $scheme (@schemes) {
    warn "$prog_name: Printing scheme $scheme\n" if $verbose>0;

    local(@keys)=eval "keys \%${scheme}_data";
    if (@keys == 1) {
      warn "$prog_name: Skipping scheme $scheme: only 1 data item\n";
      next;
    }
    local($datafile)="$output_file-${scheme}.dat";
    open (DATAFILE,">$datafile")  || die "Could not create '$datafile' - $!\n";
    local($maxx,$maxy,$minx,$miny)=''x 4;
    foreach $key (sort @keys) {
      $val=eval "\$${scheme}_data\{'$key'\}";
      $maxx=$key if !$maxx || $key gt $maxx;
      $maxy=$val if !$maxy || $val gt $maxy;
      $minx=$key if !$minx || $key lt $minx;
      $miny=$val if !$miny || $val lt $miny;
      print DATAFILE "$key $val\n";
    }
    close (DATAFILE);

    local($gnuplotfile)="$output_file-${scheme}.gnu";
    open (GNUPLOT,">$gnuplotfile") || die "Could not create '$gnuplotfile' - $!\n";

    local($xlabel)=$scheme;
    $xlabel=~ s/^per_//;
    $xlabel=~ s/^(.)(.*)$/\U$1\L$2/;
    local($outputfile)=$datafile;
    $outputfile=~ s/dat$/xpm/o;
    print GNUPLOT "set xlabel '$xlabel'\n";
    local($ylabel)=($sum eq 'accesses') ? "Accesses" : "Bytes"; 
#set xrange [$minx:$maxx]
#set yrange [$miny:$maxy]
    print GNUPLOT <<"EOT";
set term pbm color
set output '$outputfile' 
set xtics 0,1
set noborder
set tics out
plot '$datafile' using 1:2 title '$ylabel' with lines
EOT
    close (GNUPLOT);

  }
}


# MAIN PROGRAM
#
#
#
#

&set_prog_name;

# Parse options
&handle_config_options(*ARGV);
($usage,$scheme,$sum)=&parse_local_options(*ARGV);
$usage=&remove_remaining_options(*ARGV) if !$usage;
if (!$scheme) {
  warn "$prog_name: No schemes given\n";
  $usage=1;
}
if (!$sum) {
  warn "$prog_name: Must choose a summary type: one of 'accesses' or 'bytes'\n";
  $usage=1;
}
$usage=1 if !$usage && !@ARGV;

die <<"EOT" if $usage;
USAGE: $prog_name [config options] [--scheme=schemes] [--sum=accesses|bytes]
       output file [count file]
EOT

# Next argument is output file
$output_file=shift @ARGV;

# Any remaining argument is count file
$count_file=shift @ARGV || "-";

&print_config_info if $verbose>2;

local($allschemes)=0;
local(@schemes)=();
if ($scheme eq 'all') {
  $allschemes=1;
} else {
  @schemes=split(/[ ,]/,$scheme);
}

&count2gnuplot($output_file,$count_file,$sum,$allschemes,@schemes);

exit 0;
