#!/usr/bin/perl -w
# print active job properties

use strict;
use warnings;
use Data::Dumper;

#use OAR::IO;
use Getopt::Long;

#use OAR::Version;
use OAR::Conf qw(init_conf dump_conf get_conf is_conf get_conf_with_default_param);
use OAR::Stat;

$SIG{HUP}  = sub { OAR::Stat::close_db_connection(); exit(10) };
$SIG{PIPE} = sub { OAR::Stat::close_db_connection(); exit(10) };

my $Old_umask = sprintf("%lo", umask());
umask(oct("022"));

# Read config
init_conf($ENV{OARCONFFILE});
my $Cpuset_field = get_conf("JOB_RESOURCE_MANAGER_PROPERTY_DB_FIELD");

#Try to load XML module
my $XML_enabled = 1;
unless (eval "use XML::Dumper qw(pl2xml);1") {
    $XML_enabled = 0;
}

#Try to load YAML module
my $YAML_enabled = 0;
if (eval "use YAML::Syck;1") {
    $YAML_enabled = 1;
} elsif (eval "use YAML;1") {
    $YAML_enabled = 1;
}

#Try to load JSON module
my $JSON_enabled = 1;
unless (eval "use JSON;1") {
    $JSON_enabled = 0;
}

# suitable Data::Dumper configuration for serialization
$Data::Dumper::Purity   = 1;
$Data::Dumper::Terse    = 1;
$Data::Dumper::Indent   = 1;
$Data::Dumper::Deepcopy = 1;

### Variables declaration ###
my $Printed_jobs = 0;

my @job_ids;
my $array_id;
my $compact;
my $full_view;
my $state;
my $sql_property;
my $XML_mode;
my $YAML_mode;
my $JSON_mode;
my $DUMPER_mode;
my $gantt_query;
my $accounting_query;
my $events_query;
my $properties_query;
my $usage;
my $version;
my $user;
my $text_format = get_conf_with_default_param("OARSTAT_DEFAULT_OUTPUT_FORMAT", "1");
my $other_users_request =
  get_conf_with_default_param("OARSTAT_SHOW_OTHER_USERS_INITIAL_REQUEST", "no");
$text_format = $ENV{OAR_OARSTAT_OUTPUT_FORMAT} if (defined($ENV{OAR_OARSTAT_OUTPUT_FORMAT}));
### END Variables declaration ###

### Main ###

# parse command line option
Getopt::Long::Configure("gnu_getopt");
GetOptions(
    "help|h"       => \$usage,
    "version|V"    => \$version,
    "job|j:i"      => \@job_ids,
    "full|f"       => \$full_view,
    "state|s"      => \$state,
    "user|u:s"     => \$user,
    "array:i"      => \$array_id,
    "compact|c"    => \$compact,
    "gantt|g=s"    => \$gantt_query,
    "events|e"     => \$events_query,
    "properties|p" => \$properties_query,
    "accounting=s" => \$accounting_query,
    "sql=s"        => \$sql_property,
    "xml|X"        => \$XML_mode,
    "yaml|Y"       => \$YAML_mode,
    "json|J"       => \$JSON_mode,
    "dumper|D"     => \$DUMPER_mode,
    "format=s"     => \$text_format
  ) or
  exit(1);

if ($usage) {
    &print_usage;
    exit(0);
}

if ($version) {
    &print_oar_version;
    exit(0);
}

if (defined($XML_mode) and $XML_enabled != 1) {
    warn(
        "No Perl XML module is available on the system. If required, ask your admin to install one.\n"
    );
    exit(1);
}
if (defined($YAML_mode) and $YAML_enabled != 1) {
    warn(
        "No Perl Yaml module is available on the system. If required, ask your admin to install one.\n"
    );
    exit(1);
}
if (defined($JSON_mode) and $JSON_enabled != 1) {
    warn(
        "No Perl JSON module is available on the system. If required, ask your admin to install one.\n"
    );
    exit(1);
}

$user = $ENV{OARDO_USER} if (defined($user) and ($user eq ''));

if ($#job_ids == 0 and $job_ids[0] == 0) {
    shift @job_ids;
    if (exists($ENV{OAR_JOB_ID})) {
        push(@job_ids, $ENV{OAR_JOB_ID});
    } elsif (exists($ENV{OAR_JOBID})) {
        push(@job_ids, $ENV{OAR_JOBID});
    } else {
        die("/!\\ ERROR: No job id provided in command line or environment variables\n");
    }
}

if (defined($array_id) && $array_id != 0 && (scalar @job_ids > 0)) {
    warn(
        "/!\\ ERROR: Conflicting Job IDs and Array IDs (--array and -j cannot be used together)\n");
    exit(1);
}

if (defined($compact) &&
    (defined($XML_mode) || defined($YAML_mode) || defined($JSON_mode) || defined($full_view))) {
    warn("/!\\ ERROR: Compact view cannot be used with exports or full view\n");
    exit(1);
}

if (defined($properties_query) && defined($sql_property)) {
    warn("/!\\ ERROR: Options --sql and -p cannot be used together\n");
    exit(1);
}

if ((defined($XML_mode) || defined($YAML_mode) || defined($JSON_mode) || defined($DUMPER_mode))) {
    $full_view = 1;
}

OAR::Stat::open_db_connection() or die "DB connection error, exiting.\n";

if (defined($gantt_query)) {
    &print_gantt;
} elsif (defined($accounting_query)) {
    &show_accounting;
} elsif (defined($events_query)) {
    &print_events;
} elsif (defined($properties_query)) {
    &print_properties;
} elsif (defined($state)) {
    &print_state;
} else {
    &print_job;
}

OAR::Stat::close_db_connection();
exit(0);

### END Main ###

### Print Methods ###

sub print_usage {
    print <<EOS;
Usage: oarstat [-X|-Y|-D|-f|-s] [-j [job_id]|--array array_id] [--sql SQL_properties] [-u [user]] [--array] [--compact] [--format num]
       oarstat [-X|-Y|-J|-D] [-e|-p] [-j jobid|--array array_id]
       oarstat [-X|-Y|-J|-D] --gantt "YYYY-MM-DD hh:mm:ss, YYYY-MM-DD hh:mm:ss"
       oarstat --accounting "YYYY-MM-DD, YYYY-MM-DD"

Print job information

Options:
  -j, --job                 show informations for a given job
  -f, --full                show the full information
  -s, --state               show only the state of a job (optimized query)
  -u, --user                show informations a given user
      --array               show informations for the specified array_job(s) and
                            toggle array view in
  -c, --compact             prints a single line for array jobs
  -g, --gantt               show jobs information between two date-times
  -e, --events              show job events
  -p, --properties          show job properties
      --accounting          show accounting information between two dates
      --sql                 restricts display by applying the SQL where clause
                            on the table jobs (ex: "project = 'p1'")
      --format              select the text output format. Available values
                            are:
                              - 1
                              - 2
  -D, --dumper              print result in DUMPER format
  -X, --xml                 print result in XML format
  -Y, --yaml                print result in YAML format
  -J, --json                print result in JSON format
  -V, --version             print OAR version number
  -h, --help                show this help screen
EOS
}

sub print_events {
    if (defined($array_id) && $array_id != 0) {
        push(@job_ids, OAR::Stat::get_array_job_ids($array_id));
    }

    my $events = OAR::Stat::get_events(\@job_ids);
    my %events_dump;
    if (defined($events)) {
        my $lines = "";
        foreach my $event_hashref (@$events) {
            my @split_description = split("\n", $event_hashref->{description});
            my $header_str        = sprintf("%s> [%s] %s: ",
                OAR::Stat::local_to_sql($event_hashref->{'date'}),
                $event_hashref->{'job_id'},
                $event_hashref->{'type'});
            for (my $i = 0; $i <= $#split_description; $i++) {
                if ($i == 0) {
                    $lines = $lines . $header_str . $split_description[$i] . "\n";
                } else {
                    $lines = $lines . " " x length($header_str) . $split_description[$i] . "\n";
                }
            }

            push @{ $events_dump{ $event_hashref->{'job_id'} } },
              { 'date'        => $event_hashref->{'date'},
                'description' => $event_hashref->{'description'},
                'type'        => $event_hashref->{'type'} };
        }

        if (dump_data(\%events_dump) == 0 && !print("$lines")) {
            OAR::Stat::close_db_connection();
            exit(5);
        }
    } else {
        warn("No job specified\n");
        OAR::Stat::close_db_connection();
        exit(1);
    }
}

sub print_gantt {
    my $hist = OAR::Stat::get_gantt($gantt_query, $text_format);
    if (defined($hist)) {
        if (dump_data($hist) == 0) {
            $Data::Dumper::Purity   = 1;
            $Data::Dumper::Terse    = 1;
            $Data::Dumper::Indent   = 1;
            $Data::Dumper::Deepcopy = 0;
            print(Dumper($hist));
        }
    } else {
        warn("Bad syntax for --gantt\n");
        OAR::Stat::close_db_connection();
        exit(1);
    }
}

sub print_job {
    my $jobs;
    if ($#job_ids < 0) {
        if (defined($sql_property)) {
            $jobs = OAR::Stat::get_jobs_with_given_properties($sql_property);
        } elsif (defined($array_id) && $array_id != 0) {
            $jobs = OAR::Stat::get_array_subjobs($array_id);
        } else {
            $jobs = OAR::Stat::get_all_jobs_for_user($user);
            if ($compact) {
                $jobs = OAR::Stat::compact_arrays($jobs);
            }
        }
    } elsif ($#job_ids >= 0) {
        $jobs = OAR::Stat::get_specific_jobs(\@job_ids);
    }
    print_job_data($jobs);
}

sub print_job_data($) {
    my $job_array = shift;

    my $data;
    if (defined($DUMPER_mode) or
        defined($XML_mode)  or
        defined($YAML_mode) or
        defined($JSON_mode) or
        defined($full_view)) {
        foreach my $j (@{$job_array}) {
            $data->{ $j->{job_id} } = OAR::Stat::get_job_data($j, $full_view, $text_format);
        }
    }

    if (dump_data($data) == 0) {
        my %hashestat = (
            'Waiting'          => 'W',
            'toLaunch'         => 'L',
            'Launching'        => 'L',
            'Hold'             => 'H',
            'Running'          => 'R',
            'Terminated'       => 'T',
            'Error'            => 'E',
            'toError'          => 'E',
            'Finishing'        => 'F',
            'Suspended'        => 'S',
            'Resuming'         => 'S',
            'toAckReservation' => 'W',
            'NA'               => '-');

        foreach my $job_info (@{$job_array}) {
            if (defined($full_view)) {
                if ($text_format eq "3") {
                    print("id: $job_info->{job_id}\n");
                } else {
                    print("Job_Id: $job_info->{job_id}\n");
                }
                $job_info->{job_name} = '' if (!defined($job_info->{job_name}));
                if ($text_format eq "3") {
                    print("    array_id = $job_info->{array_id}\n");
                } else {
                    print("    job_array_id = $job_info->{array_id}\n");
                }
                if ($text_format eq "3") {
                    print("    array_index = $job_info->{array_index}\n");
                } else {
                    print("    job_array_index = $job_info->{array_index}\n");
                }
                print("    name = $job_info->{job_name}\n");
                print("    project = $job_info->{project}\n");
                print("    owner = $job_info->{job_user}\n");
                print("    state = $job_info->{state}\n");
                print("    wanted_resources = $data->{$job_info->{job_id}}->{wanted_resources}\n");
                print("    types = " .
                      join(", ", @{ $data->{ $job_info->{job_id} }->{types} }) . "\n");
                print("    dependencies = " .
                      join(" ", @{ $data->{ $job_info->{job_id} }->{dependencies} }) . "\n");
                print("    assigned_resources = " .
                      join("+", @{ $data->{ $job_info->{job_id} }->{assigned_resources} }) . "\n");
                print("    assigned_hostnames = " .
                      join("+", @{ $data->{ $job_info->{job_id} }->{assigned_network_address} }) .
                      "\n");
                print("    queue = $job_info->{queue_name}\n");
                $job_info->{command} = '' if (!defined($job_info->{command}));
                print("    command = $job_info->{command}\n");

                if (defined($job_info->{exit_code})) {
                    my $exit_code = $job_info->{exit_code} >> 8;
                    my $exit_num  = $job_info->{exit_code} & 127;
                    my $exit_core = $job_info->{exit_code} & 128;
                    print(
                        "    exit_code = $job_info->{exit_code} ($exit_code,$exit_num,$exit_core)\n"
                    );
                }
                if ($text_format eq "3") {
                    print("    launching_directory = $job_info->{launching_directory}\n");
                } else {
                    print("    launchingDirectory = $job_info->{launching_directory}\n");
                }
                print("    stdout_file = $data->{$job_info->{job_id}}->{stdout_file}\n");
                print("    stderr_file = $data->{$job_info->{job_id}}->{stderr_file}\n");
                if ($text_format eq "3") {
                    print("    type = $job_info->{job_type}\n");
                } else {
                    print("    jobType = $job_info->{job_type}\n");
                }
                print("    properties = $job_info->{properties}\n");
                print("    reservation = $job_info->{reservation}\n");
                if (defined $data->{ $job_info->{job_id} }->{'reserved_resources'}) {
                    print("    reserved_resources = ");
                    my @tmp_array_ok;
                    my @tmp_array_ko;
                    for my $r (keys %{ $data->{ $job_info->{job_id} }->{'reserved_resources'} }) {
                        if ($data->{ $job_info->{job_id} }->{'reserved_resources'}->{$r}
                            ->{'current_state'} eq "Alive") {
                            push(@tmp_array_ok, $r);
                        } else {
                            push(@tmp_array_ko, $r);
                        }
                    }
                    my $tmp_str_ok = join("+", sort ({ $a <=> $b } @tmp_array_ok));
                    my $tmp_str_ko = join("+", sort ({ $a <=> $b } @tmp_array_ko));
                    if ($tmp_str_ok ne "") {
                        print $tmp_str_ok;
                    } else {
                        print("none");
                    }
                    if ($tmp_str_ko ne "") {
                        print "+($tmp_str_ko)";
                    }
                    print("\n");
                }
                if (!defined($data->{ $job_info->{job_id} }->{walltime})) {
                    $data->{ $job_info->{job_id} }->{walltime} = '';
                } else {
                    $data->{ $job_info->{job_id} }->{walltime} =
                      OAR::Stat::duration_to_sql($data->{ $job_info->{job_id} }->{walltime});
                }
                print("    walltime = $data->{$job_info->{job_id}}->{walltime}\n");
                if ($text_format eq "3") {
                    print("    submission_time = " .
                          OAR::Stat::local_to_sql($job_info->{submission_time}) . "\n");
                    print("    start_time = " .
                          OAR::Stat::local_to_sql($job_info->{start_time}) . "\n")
                      if ($job_info->{start_time} > 0);
                    print(
                        "    stop_time = " . OAR::Stat::local_to_sql($job_info->{stop_time}) . "\n")
                      if ($job_info->{stop_time} > 0);
                } else {
                    print("    submissionTime = " .
                          OAR::Stat::local_to_sql($job_info->{submission_time}) . "\n");
                    print("    startTime = " .
                          OAR::Stat::local_to_sql($job_info->{start_time}) . "\n")
                      if ($job_info->{start_time} > 0);
                    print(
                        "    stopTime = " . OAR::Stat::local_to_sql($job_info->{stop_time}) . "\n")
                      if ($job_info->{stop_time} > 0);
                }
                if (defined($data->{ $job_info->{job_id} }->{cpuset_name})) {
                    print("    cpuset_name = $data->{$job_info->{job_id}}->{cpuset_name}\n");
                }
                if (   (lc($other_users_request) eq "yes" and defined($job_info->{initial_request}))
                    or
                    (   (defined($job_info->{initial_request})) and
                        (($ENV{OARDO_USER} eq $job_info->{job_user}) or
                            ($ENV{OARDO_USER} eq "oar") or
                            ($ENV{OARDO_USER} eq "root")))
                ) {
                    print("    initial_request = $job_info->{initial_request}\n");
                } else {
                    print("    initial_request = \n");
                }
                print("    message = $job_info->{message}\n");
                if ($text_format eq "3") {
                    if (!defined($data->{ $job_info->{job_id} }->{scheduled_start})) {
                        $data->{ $job_info->{job_id} }->{scheduled_start} = "no prediction";
                    } else {
                        $data->{ $job_info->{job_id} }->{scheduled_start} =
                          OAR::Stat::local_to_sql(
                            $data->{ $job_info->{job_id} }->{scheduled_start});
                    }
                    print(
                        "    scheduled_start = $data->{$job_info->{job_id}}->{scheduled_start}\n");
                } else {
                    if (!defined($data->{ $job_info->{job_id} }->{scheduledStart})) {
                        $data->{ $job_info->{job_id} }->{scheduledStart} = "no prediction";
                    } else {
                        $data->{ $job_info->{job_id} }->{scheduledStart} =
                          OAR::Stat::local_to_sql($data->{ $job_info->{job_id} }->{scheduledStart});
                    }
                    print("    scheduledStart = $data->{$job_info->{job_id}}->{scheduledStart}\n");
                }
                print("    resubmit_job_id = $job_info->{resubmit_job_id}\n");
                print("    events = \n");
                foreach my $e (@{ $data->{ $job_info->{job_id} }->{events} }) {
                    my $header_str        = OAR::Stat::local_to_sql($e->{date}) . "> $e->{type}: ";
                    my @split_description = split("\n", $e->{description});
                    for (my $i = 0; $i <= $#split_description; $i++) {
                        if ($i == 0) {
                            print($header_str . $split_description[$i] . "\n");
                        } else {
                            print " " x length($header_str);
                            print($split_description[$i] . "\n");
                        }
                    }
                }
                print("\n");
            } else {
                if (defined($array_id)) {
                    if ($text_format eq "2") {
                        if ($Printed_jobs == 0) {
                            print <<EOS;
Job id    A. id     index S User     Duration   System message
--------- --------- ----- - -------- ---------- --------------------------------
EOS
                        }
                        $job_info->{job_name} = '' if (!defined($job_info->{job_name}));
                        $job_info->{message}  = '' if (!defined($job_info->{message}));
                        printf(
                            "%-9.9s %-9.9s %-5.5s %1.1s %-8.8s %10.10s %s\n",
                            $job_info->{job_id},
                            $job_info->{'array_id'},
                            $job_info->{'array_index'},
                            $hashestat{ $job_info->{state} },
                            $job_info->{job_user},
                            OAR::Stat::get_job_duration(
                                $job_info->{start_time},
                                $job_info->{stop_time}
                            ),
                            $job_info->{message});
                        $Printed_jobs++;
                    } else {
                        if ($Printed_jobs == 0) {
                            print <<EOS;
Job id    A. id     A. index  Name       User     Submission Date     S Queue
--------- --------- --------- ---------- -------- ------------------- - --------
EOS
                        }

                        #$job_info->{'command'} = '' if (!defined($job_info->{'command'}));
                        $job_info->{job_name} = '' if (!defined($job_info->{job_name}));
                        printf(
                            "%-9.9s %-9.9s %-9.9s %-10.10s %-8.8s %-19.19s %1.1s %-8.8s\n",
                            $job_info->{'job_id'},
                            $job_info->{'array_id'},
                            $job_info->{'array_index'},
                            $job_info->{'job_name'},
                            $job_info->{'job_user'},
                            OAR::Stat::local_to_sql($job_info->{'submission_time'}),
                            $hashestat{ $job_info->{'state'} },
                            $job_info->{'queue_name'});
                        $Printed_jobs++;
                    }
                } else {
                    if ($text_format eq "2") {
                        if ($Printed_jobs == 0) {
                            print <<EOS;
Job id    S User     Duration   System message
--------- - -------- ---------- ------------------------------------------------
EOS
                        }
                        $job_info->{job_name} = '' if (!defined($job_info->{job_name}));
                        $job_info->{message}  = '' if (!defined($job_info->{message}));
                        printf(
                            "%-9.9s %1.1s %-8.8s %10.10s %s\n",
                            $job_info->{job_id},
                            $hashestat{ $job_info->{state} },
                            $job_info->{job_user},
                            OAR::Stat::get_job_duration(
                                $job_info->{start_time},
                                $job_info->{stop_time}
                            ),
                            $job_info->{message});
                    } else {
                        if ($Printed_jobs == 0) {
                            print <<EOS;
Job id     Name           User           Submission Date     S Queue
---------- -------------- -------------- ------------------- - ----------
EOS
                        }

                        #$job_info->{'command'} = '' if (!defined($job_info->{'command'}));
                        $job_info->{job_name} = '' if (!defined($job_info->{job_name}));
                        printf(
                            "%-10.10s %-14.14s %-14.14s %-19.19s %1.1s %-10.10s\n",
                            $job_info->{'job_id'},
                            $job_info->{'job_name'},
                            $job_info->{'job_user'},
                            OAR::Stat::local_to_sql($job_info->{'submission_time'}),
                            $hashestat{ $job_info->{'state'} },
                            $job_info->{'queue_name'});
                    }
                    $Printed_jobs++;
                }
            }
        }
    }
}

sub print_job_state_data($) {
    my $data = shift;

    if (dump_data($data) == 0) {
        foreach my $j (keys %$data) {
            print "$j: " . $data->{$j} . "\n";
        }
    }
}

sub dump_data($) {
    my $data = shift;
    if (defined($data)) {
        if (defined($JSON_mode)) {
            print(JSON->new->pretty(1)->encode($data));
            return 1;
        }
        if (defined($YAML_mode)) {
            print(Dump($data));
            return 2;
        }
        if (defined($DUMPER_mode)) {
            print(Dumper($data));
            return 3;
        }
        if (defined($XML_mode)) {
            my $dump = new XML::Dumper;
            $dump->dtd;
            print($dump->pl2xml($data));
            return 4;
        }
    }
    return 0;
}

sub print_oar_version {
    print "OAR version: " . OAR::Stat::get_oar_version() . "\n";
}

sub print_properties {
    if (defined($array_id) && $array_id != 0) {
        push(@job_ids, OAR::Stat::get_array_job_ids($array_id));
    }

    if ($#job_ids >= 0) {
        my @resources;
        my %resources_dump;
        foreach my $j (@job_ids) {
            my @res = OAR::Stat::get_job_resources_properties($j);
            if (@res > 0) {
                push(@resources, @res);
                $resources_dump{$j} = \@res;
            }
        }

        my $lines = "";
        foreach my $r (@resources) {
            my $line = "";
            foreach my $p (keys(%{$r})) {
                if (OAR::Tools::check_resource_system_property($p) != 1) {
                    $r->{$p} = "" if (!defined($r->{$p}));
                    $line .= " $p = '$r->{$p}' ,";
                }
            }
            chop($line);
            $lines = $lines . $line . "\n";
        }

        if (dump_data(\%resources_dump) == 0 && !print("$lines")) {
            OAR::Stat::close_db_connection();
            exit(5);
        }
    } else {
        warn("No job specified\n");
        OAR::Stat::close_db_connection();
        exit(1);
    }
}

sub print_state {
    my %job_state;
    if ($#job_ids < 0) {
        warn("--state can only be used with an id\n");
        OAR::Stat::close_db_connection();
        exit(1);
    } elsif ($#job_ids >= 0) {
        foreach my $j (@job_ids) {
            my $state_string = OAR::Stat::get_job_state($j);
            if (defined($state_string)) {
                $job_state{$j} = $state_string;
            }
        }
    }
    print_job_state_data(\%job_state);
}

sub show_accounting {
    if ($accounting_query =~ m/\s*(\d{4}\-\d{1,2}\-\d{1,2})\s*,\s*(\d{4}\-\d{1,2}\-\d{1,2})\s*/m) {
        my ($date1, $date2) = ($1 . " 00:00:00", $2 . " 00:00:00");
        my $login;
        my $Consumptions = OAR::Stat::get_accounting_summary(
            OAR::Stat::sql_to_local($date1),
            OAR::Stat::sql_to_local($date2),
            $user, $sql_property);

        # One user output
        if (defined($user)) {
            my $asked = 0;
            $asked = $Consumptions->{$user}->{ASKED} if (defined($Consumptions->{$user}->{ASKED}));
            my $used = 0;
            $used = $Consumptions->{$user}->{USED} if (defined($Consumptions->{$user}->{USED}));
            print "Usage summary for user '$user' from $1 to $2:\n";
            print "-------------------------------------------------------------\n";
            if (defined($Consumptions->{$user}->{begin})) {
                printf("%-28s %s\n",
                    "Start of the first window:",
                    OAR::Stat::local_to_sql($Consumptions->{$user}->{begin}));
            } else {
                printf("%-28s %s\n", "Start of the first window:", "No window found");
            }
            if (defined($Consumptions->{$user}->{end})) {
                printf("%-28s %s\n",
                    "End of the last window:",
                    OAR::Stat::local_to_sql($Consumptions->{$user}->{end}));
            } else {
                printf("%-28s %s\n", "End of the last window:", "No window found");
            }
            printf(
                "%-28s %s ( %s)\n",
                "Asked consumption:",
                $asked, OAR::Stat::get_duration($asked));
            printf("%-28s %s ( %s)\n", "Used consumption:", $used, OAR::Stat::get_duration($used));
            print "By project consumption:\n";
            $Consumptions =
              OAR::Stat::get_accounting_summary_byproject(OAR::Stat::sql_to_local($date1),
                OAR::Stat::sql_to_local($date2), $user);
            foreach my $project (keys %{$Consumptions}) {
                print "  $project:\n";
                $asked = 0;
                $asked = $Consumptions->{$project}->{ASKED}->{$user}
                  if (defined($Consumptions->{$project}->{ASKED}->{$user}));
                $used = 0;
                $used = $Consumptions->{$project}->{USED}->{$user}
                  if (defined($Consumptions->{$project}->{USED}->{$user}));
                printf("%-28s %s ( %s)\n", "    Asked:", $asked, OAR::Stat::get_duration($asked));
                printf("%-28s %s ( %s)\n", "    Used:",  $used,  OAR::Stat::get_duration($used));
                if (
                    my @last_karma = OAR::Stat::get_last_project_karma(
                        $user, $project, OAR::Stat::sql_to_local($date2))
                ) {
                    if ($last_karma[0] =~ m/.*Karma\s*\=\s*(\d+\.\d+)/m) {
                        printf("%-28s %s\n", "    Last Karma:", $1);
                    }
                }
            }

            # All users array output
        } else {
            print <<EOS;
    User       First window starts  Last window ends     Asked (seconds)  Used (seconds)
    ---------- -------------------- -------------------- ---------------- ----------------
EOS
            foreach $login (keys %{$Consumptions}) {
                if (!defined($Consumptions->{$login}->{ASKED})) {
                    $Consumptions->{$login}->{ASKED} = 0;
                }
                if (!defined($Consumptions->{$login}->{USED})) {
                    $Consumptions->{$login}->{USED} = 0;
                }
                printf(
                    "%-10.10s %-19s  %-19s  %16s %16s\n",
                    $login,
                    OAR::Stat::local_to_sql($Consumptions->{$login}->{begin}),
                    OAR::Stat::local_to_sql($Consumptions->{$login}->{end}),
                    $Consumptions->{$login}->{ASKED},
                    $Consumptions->{$login}->{USED});
            }
        }

    } else {
        print("Bad syntax for --accounting\n");
        OAR::Stat::close_db_connection();
        exit(1);
    }
}

### END Print Methods ###
