#!/usr/bin/perl

# This is a program that aggregates and outputs network traffic
# information (usually as a graph).

# Copyright 2009 Corey Hickey


# This file is part of Captrap.
#
# Captrap 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 3 of the License, or
# (at your option) any later version.
#
# Captrap 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 Captrap.  If not, see <http://www.gnu.org/licenses/>.


use strict;
use warnings FATAL => 'all';

# for development using a different Captrap module
use lib "lib";
use Captrap qw(:misc :actions :args :config :db);
use Captrap::Graph qw(:graph :param);

# -----------------------------------------------------------------------------
# printing
# -----------------------------------------------------------------------------

# print main help info
sub usage {
  my $common = shift; # unused
  my $actions = mk_actions();
  my $actions_text = describe_actions($actions);
  print "
This is a script for writing Captrap graphs to files.

captrap_graph [ACTION] [[ACTION-PARAMETERS]] ...

ACTIONS

$actions_text

EXIT STATUS

0              Everything is ok.

1              No arguments given; usage information was shown.

2              Invalid argument.

3              There was a problem executing an action.


EXAMPLES

Write a monthly graph to a file:
captrap_graph -write monthly.png \
    \"graph=per&per=month&start=2008-08-01T00:00:00&end=2009-08-01T00:00:00\"

Display an hourly graph (requires 'display' from imagemagick):
captrap_graph -write - \
    \"graph=per&per=hour&start=2009-08-12T00:00:00&end=2009-08-13T00:00:00\"

"
}


# list all parameters
sub list_params {
  my $common = shift;
  my $param_info = mk_param_info($common->{config});
  arg_list_params($param_info);
}
 

# -----------------------------------------------------------------------------
# graph writing
# -----------------------------------------------------------------------------

# open a file and write a graph to it
sub do_write {
  my $common = shift;
  my $file = shift;
  my $params = shift;
  my $param_info = mk_param_info($common->{config});
  arg_handle_params($common, $param_info, \&arg_mk_graph, $params, $file);
  # If we get here, it worked; otherwise, we've already exited.
  # So, return 0 to signify an action that ran ok.
  return 0;
}


# use provided cgi parameters to call the graphing subroutine
sub arg_mk_graph {
  my $common = shift; # hash ref
  my $params = shift; # hash ref
  my $file = shift;
  # do some additional parameter validation
  my $err = params_ok($common, $params);
  if (@$err) {
    # problems!
    arg_print_errors($common, $err);
    return undef;
  }
  return write_output_to_file($common, $params, $file, \&mk_graph, 0);
}

# print errors found by params_ok();
sub arg_print_errors {
  my $common = shift; # hash ref
  my $err = shift; # array ref
  my $config = $common->{config};
  print STDERR "Sorry--your parameters parsed ok, but they cannot be used:\n\n";
  foreach my $item (@$err) {
    print STDERR "$item\n\n";
  }
}


# -----------------------------------------------------------------------------
# actions info
# -----------------------------------------------------------------------------

# return a hash of action info
sub mk_actions {
  my $actions = mk_ixhash();
  %$actions = (
    "-help" => {
      func => \&usage,
      args => [],
      desc => "
          Print this usage text.
      ",
    },
    "-list-parameters" => {
      func => \&list_params,
      args => [],
      desc => "
          Print a list of valid parameters.
      ",
    },
    "-write" => {
      func => \&do_write,
      args => [ qw(FILE PARAMETERS) ],
      desc => "
          Write a graph to a file, unless the file already exists. To write to
          stdout, specify the file as '-' (if you really want to create a file
          named '-', specify './-'). The filename must be followed by a list of
          parameters in the usual URL form (as in param1=value1&param2=value2).
          Be sure to surround the parameters with single-quotes if necessary,
          to avoid having the shell interpret the ampersands.
      ",
    }
  );
  return $actions;
}

# ----------------------------------------------------------------------------
# parse the arguments and take actions
if (! @ARGV) {
  usage();
  exit(1);
}
my $actions = mk_actions();
check_args(\@ARGV, $actions);

my $config = parse_config();
my $common = {
  config => $config,
  dbh    => mk_dbh($config),
};

do_args($common, \@ARGV, $actions);

$common->{dbh}->disconnect();
exit(0);
