#!/usr/local/bin/python3

from operator import attrgetter
import sys

ITEM_KEY, my_items, have_item = 'Item:', [], False
# Default for value_of_time can be overridden in data file
VALUE_OF_TIME_KEY, value_of_time = 'Value of time:', 50.0

class Life_item:
  # What's my time worth, not being able to do something else while I'm tending to the things that own me.
  # cost is in dollars as a float
  # lifespan is in years as a float

    def __init__(self, name, cost, lifespan):
        self.name, self.cost, self.lifespan, self.maintainers = name, float(cost), float(lifespan), []

    def add_maintainer(self, name, cost, period, time_spent):
        self.maintainers.append(Maintainer(name, cost, period, time_spent))
        
    def replacement_cost_per_day(self):
        result = 0.0
        
        if self.lifespan != 0.0:
            result = self.cost / self.lifespan / 365.0
            
        return result

    def __str__(self):
        s = """
-------------------------------------------
Item name = {0:s}
Cost      = ${1:.2f}""".format(self.name, self.cost)
        if self.lifespan != 0.0:
            s += '\nLifespan  = {0:.2f} years'.format(self.lifespan)
        else:
            s += '\nLifespan  = n/a'
        for maintainer in self.maintainers:
            s += maintainer.__str__()
        return s

class Maintainer:
  # cost is in dollars as a float
  # period is in days as an integer
  # time_spent is in hours as a float

    def __init__(self, name, cost, period, time_spent):
        self.name, self.cost, self.period, self.time_spent = name, float(cost), int(period), float(time_spent)

    def time_per_day(self):
        return self.time_spent / self.period

    def cost_per_day(self):
        return self.cost / self.period

    def __str__(self):
        if self.period == 1:
            plural = ''
        else:
            plural = 's'
        return """

   Maintenance name = {0:s}
   Cost             = ${1:.2f} every {2:d} day{3:s}
   Time spent       = {4:.2f} hours""".format(self.name, self.cost, self.period, plural, self.time_spent)


if len(sys.argv) == 2:
    in_file = sys.argv[1]
else:
    in_file = 'jim.dat'

f = open(in_file, 'r')
# Collect data into structures 
# value of time is in dollars as a float
try:
    for a_line in f:
        if a_line[0] == '#':
            continue
        ar = a_line.rstrip().split(', ')
        if ar[0] == VALUE_OF_TIME_KEY:
            value_of_time = float(ar[1])
        elif ar[0] == ITEM_KEY:
            if(have_item):
                my_items.append(an_item)

            an_item = Life_item(ar[1], ar[2], ar[3])
            have_item = True
        else:
            an_item.add_maintainer(ar[0], ar[1], ar[2], ar[3])
except ValueError as e:
    print('\nValueError exception occurred:', e)
    exit(0)

my_items.append(an_item)
f.close()

# Sort items and maintainers within each item
my_items.sort(key = attrgetter('name'))
for item in my_items:
    item.maintainers.sort(key = attrgetter('name'))

# All sorted, go to town
total_daily_maintenance_time, total_daily_maintenance_cost, total_daily_replacement_cost = 0.0, 0.0, 0.0

for item in my_items:
    print(item)
    total_daily_replacement_cost += item.replacement_cost_per_day()
    
    for maintainer in item.maintainers:
        total_daily_maintenance_time +=  maintainer.time_per_day()
        total_daily_maintenance_cost +=  maintainer.cost_per_day()
        
total_daily_real_costs = total_daily_maintenance_cost + total_daily_replacement_cost
total_daily_time_costs = total_daily_maintenance_time * value_of_time
total_daily_costs = total_daily_real_costs + total_daily_time_costs
print("""

===========================================
             Total Daily Costs
===========================================

Replacement actual = ${0:6.2f}
Maintenance time   = ${1:6.2f} ({2:.4f} hours at ${3:.0f}/hr)
Maintenance actual = ${4:6.2f}
Actual             = ${5:6.2f}

Cost of living     = ${6:6.2f}
""".format(total_daily_replacement_cost, total_daily_time_costs, total_daily_maintenance_time, value_of_time, total_daily_maintenance_cost, total_daily_real_costs, total_daily_costs))