#!/usr/bin/perl

=head1 NAME

viewTimesheet.pl - reads timesheet file and outputs contents with date & time

=head1 SYNOPSIS

  # see the "usage" message, open default timesheet and view it 
  ./viewTimesheet.pl

  # open easytimer configfile, find timesheet file name there, open that timesheet and view it
  ./viewTimesheet.pl /etc/easytimer.conf

  # open easytimer timesheet file and view it
  ./viewTimesheet.pl ~/.easytimer/timesheet

=head1 DESCRIPTION

This script allows user to view date & time info in timesheet file.
Also outputs 9am, lunchtimes, 5:30pm every day (for full month).
Useful for editing timesheets where there are missing entries.

=head2 Operation

Default timesheet is $ENV{HOME}/.easytimer/timesheet 
Otherwise parse config file and look for timesheet= entry.
Otherwise try open file passed in on command line.

Gets first time in timesheet file.
Then figures out first working day of that month.
Prints non_work entries for all days which have no close real timesheet entries.

=head2 Limitations, TBDs, not TBDs

Very very very verbose output. Reduce this (add option).

Was more useful when I forgot more to fill in timesheet.
Still useful on occasion.
I believe possibly everyone in office has an equivalent script/method to 
retrospectively fill in timesheets so this may help reduce duplication of effort?

=cut

use strict;
use warnings;
use IO::Select;
use Time::Local;
use POSIX qw(strftime);
use POSIX qw(mktime);

## Declare our variables
my($conf, %conf, $key, $line, $header );

## Get the arguments or die!
$conf = $ARGV[0];
unless ($conf) {
    #die("Usage:\n\t$0 conffile\n");
    print("Usage:\n\t$0 conffile\n\t OR\n\t\t$0 timesheetfile\n");
    $conf{"timesheet"} = "$ENV{HOME}/.easytimer/timesheet";
    my(@date) = (localtime)[3,4,5];
    my $today_file = sprintf("%s.%04d.%02d.%02d", $conf{"timesheet"},
			     $date[2]+1900, $date[1]+1, $date[0] );
    $conf{"timesheet"} = $today_file;
} else {
    $_ = $conf;
    if (m/timesheet/) {
        $conf{"timesheet"} = $conf;
    } else {
        ## Parse the conffile
        %conf = &parseConf($conf);
    }
}

my $view = 1;

####################
## Date & Time
####################

#       0    1    2     3     4    5     6     7     8
#my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
#    localtime(time);
	# day, month, year $date[0],$date[1]+1,$date[2]+1900;

print "Looking at Timesheet $conf{timesheet} \n";

####################
## Read in the timesheet file and print it
####################

open(TS, "<".$conf{"timesheet"}) 
    or die("Error opening ". $conf{"timesheet"} . "\n");

my $lasttimestamp = 0;
my ($yesterday530pm_ts, $yesterday530pm_str) = (0, "");

while ($line = <TS>)  {
    chomp($line);
    my @lines = split(/:/,$line);
    #my $line_str = gmtime($lines[0]);
    my $line_date = localtime($lines[0]);

    my @today0am_date = localtime($lines[0]);
    @today0am_date[0..2] = (0, 0, 0); # midnight today 0:00:00
    my $today0am_ts = &mktime(@today0am_date);
    my $today9am_ts = $today0am_ts + 9*60*60;
    my $today9am_str = localtime($today9am_ts);
    my $today530pm_ts = $today9am_ts + 8*60*60 + 1*30*60;
    my $today530pm_str = localtime($today9am_ts);
        
    # check for missing days
    while ($lasttimestamp + 24*60*60 < $lines[0]) {

	if ($lasttimestamp == 0) {
	    my @startofmonth_date = localtime($lines[0]);
	    @startofmonth_date[0..3] = (0, 0, 0, 1); # 1st day of month 0:00:00
	    $lasttimestamp = &mktime(@startofmonth_date) - 1; # day b4 1st day of month 23:59:59
	    next;
	}

	my @last9am_date = localtime($lasttimestamp + 24*60*60); # 9am next day
	@last9am_date[0..2] = (0, 0, 9); # that day 9:00:00
	my $last9am_ts = &mktime(@last9am_date);
        my $last9am_str = localtime($last9am_ts);
	my $last530pm_ts = $last9am_ts + 8*60*60 + 1*30*60;
        my $last530pm_str = localtime($last530pm_ts);
        
	if ($last9am_date[6] >= 1 && $last9am_date[6] <= 5) { # is a workday
	    #print "Add entry for 9am $last9am_ts $last9am_str\n";
	    #print "Last 5:30am $last530pm_ts $last530pm_str\n";
	    print "$last9am_str==" if ($view); 
	    print "$last9am_ts:non_work:9am there was no entry $last9am_str\n";

	    # an hour is long for lunch but also covers everything else in day
	    my $lastlunch_ts = $last9am_ts + 4*60*60;
	    my $lastlunch_str = localtime($lastlunch_ts);
	    print "$lastlunch_str==" if ($view); 
	    print "$lastlunch_ts:non_work:lunch etc... $lastlunch_str\n";
	    $lastlunch_ts = $last9am_ts + 5*60*60;
	    $lastlunch_str = localtime($lastlunch_ts);
	    print "$lastlunch_str==" if ($view); 
	    print "$lastlunch_ts:non_work:lunch etc... $lastlunch_str\n";

	    print "$last530pm_str==" if ($view);
	    print "$last530pm_ts:non_work:530pm there was no entry $last530pm_str\n";
	}

	#$lasttimestamp = $last9am_ts + 17*60*60; # midnight
	$lasttimestamp = $last530pm_ts; # honesty is the best policy

    }

    # if we are on new day 
    if ($lasttimestamp < $today0am_ts) {
	# if missing entry about 530pm for old day
	if ($lasttimestamp < $yesterday530pm_ts) {
	    print "$yesterday530pm_str==" if ($view);
	    print "$yesterday530pm_ts:non_work:530pm there was no entry $yesterday530pm_str\n";
	}
	# if missing entry about 9am for new day
	if ($today9am_ts < $lines[0]) {
	    print "$today9am_str==" if ($view);
	    print "$today9am_ts:non_work:9am there was no entry $today9am_str\n";
	}
    }

    $line = $line . "\n";
    $line = $line_date . "==" . $line if ($view);
    print $line;

    $yesterday530pm_ts = $today530pm_ts;
    $yesterday530pm_str = $today530pm_str;
    $lasttimestamp = $lines[0];
}

## Finish up, close files
close(TS);


###############
## Sub-routines
###############

## sub parseConf - reads config file into a hash
sub parseConf() {
    my($line,%conf);
    open(CONF, "<$conf") or die("Error opening $conf\n");
    while ($line = <CONF>) {
        my @line = split(/=/, $line);
	chomp($line[0]);
	chomp($line[1]);
	##TODO: All items from conf should be untainted
        $conf{$line[0]} = $line[1];
    }
    close(CONF);
    return %conf;
}