#!/usr/bin/perl
#hello there
#this script parses my daily journal and hopefully spits out a neat friendly
#convenient record object

#or maybe, some time in the future, this will talk to a real database

#USAGE: tail -n 600 /home/fenn/archived/real_life/pda_db.txt | 
#            grep -rE "work|date" > invoice.in 

use strict; use warnings;
use POSIX;

my $total = 0;
my %tally ;

my @i_start = qw(2006 10 31 00 00);
my @i_end =   qw(2007 11 31 00 00);
my $logfile = undef;
my $use_stdin = undef;

#usage
#if defined(@ARGV) {($start[1],$start[2],$end[1],$end[2]) = @ARGV;}
#($start[1],$start[2],$end[1],$end[2]) = @ARGV if defined (@ARGV);
if (defined @ARGV ) {
my $cmd = join(" ", @ARGV);
($i_start[1],$i_start[2],$i_end[1],$i_end[2],$use_stdin) = 
($cmd =~ m{(\d\d)/(\d\d)\s+(\d\d)/(\d\d)(\s+-\s?)?})
  or die "Usage: logparse 01/02 03/04 [\"-\" = use stdin is still buggy]\n";
#if (defined $use_stdin){ print "found a - \n";}
}


sub posixify {
  my ($year, $month, $day, $hour, $min) = @_;
  $year -=1900; $month -=1; $hour -=1;
  my $sec = 0; 
  my $unixtime = mktime ($sec, $min, $hour, $day, $month, $year );

  #my $readable_time = localtime($unixtime); print "$readable_time\n";
  return $unixtime;
}

sub parse {
#each line looks like this:
  # 1341 1514 work do-this do-that do-the-other, food carrot 2pc pie
  my $line, my @date=(0,0,0), my @entry_start=(0,0), my @entry_end=(0,0);
  my @tasklist;
  if($logfile) { open(LOG, $logfile) or die "$!\n";}
  elsif ($use_stdin) { open (LOG, <STDIN>);}
  else { open (LOG, "invoice.in") or die "$!\n"; }

  while ($line = <LOG>){
    if ($line =~ /^date (\d{4}) (\d{2}) (\d{2})/) { @date = ($1, $2, $3); next; }
    if ($line =~/^(\d{2})(\d{2}) (\d{2})(\d{2}).*/) { 
      # get the hour and minute timestamp for each entry
      @entry_start = ($1, $2); @entry_end = ($3, $4);
      my $elapsed=0;
      # get a list of arguments to "work", terminated by a comma or EOL
      if ($line =~ /^.* work (.*?(,|$))/) { 
        @tasklist = split(" ",$1);
        #drop entries not in the specified time frame
        if((posixify(@date, @entry_start) < posixify(@i_start)) or (posixify(@date, @entry_end) > posixify(@i_end))) { next;}
        #add em up
        $elapsed = (posixify(@date, @entry_end) - posixify(@date, @entry_start))/60;
        $total += $elapsed;
        printf "\n%d %02d/%02d %02d:%02d-%02d:%02d (%d minutes)\n", 
             @date, @entry_start, @entry_end, $elapsed;
        foreach my $task (@tasklist) {
          $task =~ s/-/ /g;
          print "  $task\n";
          my @sublist = split " ", $task;
          $tally{"$sublist[0]"} += $elapsed/scalar(@tasklist); #usually the category name
        }
      }
#      print $line;   
 #     print "\n";
      }
  }
  close LOG;
}

parse;
print "\n\n";
printf "Time interval: %02d/%02d - %02d/%02d\n", $i_start[1], $i_start[2], $i_end[1], $i_end[2];

print "Time spent in each category:\n";
#my @categories = sort keys %tally;
print "categories: ", join(", ", sort keys %tally), "\n";
foreach my $i (sort keys %tally) { printf "%-7s %d\n", $i, $tally{$i};}
printf "        %d minutes total.\n", ($total);
printf "        %d hours total.\n", ($total/60);


