#!/usr/bin/perl -w
use strict;
use Getopt::Long;
use POSIX;

sub parseint {
    return $_[0];
}
sub parsemsec {
    return $_[0]/1000;
}
sub parsetime {
    my @f= split /:/, $_[0];

    my $t=0;
    for my $f (@f) {
        $t *= 60;
        $t += $f;
    }
    return $t;
}
sub parsedate {
    my @f= split /[-\/]/, $_[0];

    return POSIX::mktime(0,0,0,$f[0], $f[1]-1, $f[2]-1900);
}
sub parsedatetime {
    my @f= split /[-\/:,]/, $_[0];

    return POSIX::mktime($f[5],$f[4],$f[3],$f[2], $f[1]-1, $f[0]-1900);
}


sub parsetimegroup {
    our %types= ( sec=>1, min=>60, hour=>3600, hr=>3600, day=>86400, week=>7*86400, month=>30.5*86400, year=>365.2422*86400 );

    if ($_[0] =~ /(\d*)([a-z]+)/) {
        my ($num, $type)= ($1,$2);
        die "unknown type: $type\n" if (!exists $types{$type});
        $num= 1 if !defined $num || $num eq '';
        return $num * $types{$type};
    }
    die "unknown type: $_[0]\n";
}
my $xcolumnparser=\&parseint;
my $groupparser=\&parseint;
my $grouping=1;
my $outputzeros;   # todo - implement
GetOptions(
    "a"=>\$outputzeros,
    "m"=>sub { $xcolumnparser=\&parsemsec; $groupparser=\&parsetimegroup; },
    "t"=>sub { $xcolumnparser=\&parsetime; $groupparser=\&parsetimegroup; },
    "d"=>sub { $xcolumnparser=\&parsedate; $groupparser=\&parsetimegroup; },
    "dt"=>sub { $xcolumnparser=\&parsedatetime; $groupparser=\&parsetimegroup; },
    "g=s"=>\$grouping,
) or die usage();

$grouping= $groupparser->($grouping);

sub usage {
    return <<__EOF__
Usage: group [-a] [-m -t | -d] [-g GROUPING]
    -a : list zero's too
    -t : first column is a time
    -d : first column is a date ( d-m-y )
    -dt : first column is a date+time ( y-m-d,h:m:s )
    -m : first column is in msecs
    -g : specify grouping, like sec or 10sec or 1000
__EOF__
}
my %x;
while (<>)
{
    s/^\s+//; s/\s+$//;
    my @f=split /\s+/, $_;
    my $x= $xcolumnparser->($f[0]) ;
    if ($grouping!=1) {
        $x = int($x/$grouping);
    }
    else {
        $x = int($x);
    }

    $x{$x} += $f[1];
}
if ($outputzeros) {
    my @x= sort {$a<=>$b} keys %x;
    for (my $x= $x[0] ; $x<$x[-1] ; $x += $grouping) {
        $x{$x} ||=0;
    }
}
for my $x (sort {$a<=>$b} keys %x) {
    printf("%8s %8d\n", $x, $x{$x});
}
