#!/usr/bin/python3

"""A simple time calculator.  Read start time, end time pairs, one per line, and tally up how much time was spent."""

import re
import sys
import time
import collections


def get_time_from_field(string):
    """Get a struct time from a time string in either of 2 formats."""
    # This is nice for Intuit time
    time_format1 = '%Y/%m/%d %I:%M%p'
    time_format2 = '%Y-%m-%d %I:%M%p'

    for time_format in (time_format1, time_format2):
        try:
            result = time.strptime(string, time_format)
        except ValueError:
            pass
        else:
            return result

    raise ValueError


def main():
    """Do the stuff. :)."""
    total = 0.0

    seconds_seen_so_far = set()

    for filename in sys.argv[1:]:
        with open(filename, 'r') as file_:

            time_dict = collections.defaultdict(float)

            for lineno, line in enumerate(file_):
                if not line.rstrip():
                    continue

                if line.startswith('#'):
                    continue

                # eliminate comments
                line = re.sub('#.*$', '', line)

                fields = line.split('-')
                len_fields = len(fields)

                if len_fields == 6:
                    # This is presumably a line with dashes for the dates.  Re-split on ' - '
                    fields = line.split(' - ')
                    len_fields = len(fields)

                if len_fields == 2:
                    # good, we have a start time and end time pair
                    pass
                else:
                    sys.stderr.write(f'lineno {lineno+1}: len(fields) != 2: {fields}\n')
                    sys.exit(1)

                start_time_string = fields[0].lstrip().rstrip()
                end_time_string = fields[1].lstrip().rstrip()

                start_time_struct = get_time_from_field(start_time_string)
                end_time_struct = get_time_from_field(end_time_string)

                date_tuple = (start_time_struct.tm_year, start_time_struct.tm_mon, start_time_struct.tm_mday)

                start_time_secs = int(time.mktime(start_time_struct))
                end_time_secs = int(time.mktime(end_time_struct))

                current_seconds_set = set(range(start_time_secs, end_time_secs))

                if current_seconds_set & seconds_seen_so_far:
                    raise SystemExit(f'Found time overlap on line {lineno+1}')

                seconds_seen_so_far |= current_seconds_set

                difference = end_time_secs - start_time_secs
                if difference < 0:
                    sys.stderr.write(f'{sys.argv[0]}: lineno {lineno+1} goes backward in time: {line}\n')
                    sys.exit(1)

                time_dict[date_tuple] += difference

    keys = list(time_dict.keys())
    keys.sort()

    for key in keys:
        day_time_string = time_dict[key] / (60.0 * 60.0)
        sys.stdout.write('Day {}-{}-{}: {:.2f} hours\n'.format(key[0], key[1], key[2], day_time_string))

        total += time_dict[key]

    total_string = total / (60.0 * 60.0)
    print('Total: {:.2f} hours\n'.format(total_string))


main()