#!/usr/bin/env python3

from argparse import ArgumentParser
import json
from datetime import datetime, timedelta

def read_json(filename):
	"""Reads the json input file specified into a list of dictionaries

    Parameters:
	filename (string): The name and path of the file to load

    Returns:
	list:list with a dictionary for each of the json lines

    Exits:
	Exits with code 1 if unable to open the file

   """
	try:
		with open(filename) as json_file:
			data = [json.loads(line) for line in json_file]
		return data
	except:
		print ("ERROR: specified input file not found or no permission to read")
		exit(1)

#Calculate the average of the duration of items with timestamp from time-window (in minutes) to time
def moving_average(data, window, time):
	"""Calculate the average of the duration of items within a time window

    Parameters:
	data (list): List of dictionaries with value for timestamp(datetime) and duration(int)
	window (int): Number of minutes to include in the rolling window
	time (datetime): The top limit for the rolling window

    Returns:
	float: average of duration values for elements of the data within the time window

   """
	#Get the duration of all lines that the timestamp is after the window start and until the last second of current evaluation time minute
	list = [i['duration'] for i in data if i['timestamp'] > time - timedelta(minutes=window) and i['timestamp'] <= time ]
	if not list:
		return 0
	return sum(list)/len(list)

def calculate_averages(data, window):
	"""Prepares the input data and print out the average duration on a time window for each minute

    Parameters:
	data (list): List of dictionaries with value for timestamp(string) and duration(int)
	window (int): Number of minutes to include in the rolling window

    Returns:

   """
	#Convert the timestamp field to datetime
	for i in range(len(data)):
		line_date = datetime.strptime(data[i]['timestamp'], '%Y-%m-%d %H:%M:%S.%f')
		data[i]['timestamp'] = line_date

	dates = [i['timestamp'] for i in data]
	min_date =  min(dates)
	max_date =  max(dates) + timedelta(minutes=1) #Add 1 minute otherwise the last minute is ignored

	#Loop through the timespan and for each minute and calculate the averages
	current_date = min_date.replace(second=0, microsecond=0)
	while current_date <= max_date:
		avg = moving_average(data, window, current_date)
		print({"date": current_date.strftime('%Y-%m-%d %H:%M:%S'), "average_delivery_time":'%g'%(avg)})
		current_date += timedelta(minutes=1)


def read_input_parameters():
	"""Reads the options from the input parameters.
Checks if all parameters are filled in and have the correct data type

    Parameters:

    Returns:
	args object with a 'filename' and a 'window_size' attribute

    Exits:
	exit with code 1 if any argument has incorrect datatype or is missing

   """
	parser = ArgumentParser()
	parser.add_argument("-i", "--input_file", dest="filename",
            help="json input file", metavar="FILE")
	parser.add_argument("-w", "--window_size", dest="window_size",
            help="window size for the moving average")
	args = parser.parse_args()

	#Check for missing arguments
	if args.filename is None or args.window_size is None:
		parser.print_help()
		exit(1)
	#Check if window size is an integer
	try:
		window_size = int(args.window_size)
		args.window_size = window_size
	except:
		print ("ERROR: specified window size is not an integer number")
		parser.print_help()
		exit(1)

	if window_size < 0:
		print ("ERROR: window size must be greater or equal to 0")
		exit(1)

	return args



args = read_input_parameters()
input_dict = read_json(args.filename)
calculate_averages(input_dict, args.window_size)

