#!/usr/bin/python3
"""
ifppcmd.py

This script processes captured packets from a pcap file, calculates statistics, and plots the deviation
of measured reception times from expected reception times.

Usage:
    python ifppcmd.py -p <pcap_file> -t <topic_id> -o <output_plot_directory>

Arguments:
    -p : Path to the pcap file to process (required)
    -t : Topic ID to be analyzed (required)
    -o : Directory to save the output plot images (optional). This directory must be created before running the script.

"""
import numpy as np

from ifpostprocessinglib.ifpostprocessing import Postprocessing as postp
import argparse

import matplotlib.pylab as plt
from datetime import datetime

def getCurrentFormattedDatetime():
    """
    Get the current date and time and format it as a string.
    """
    current_datetime = datetime.now()
    formatted_datetime = current_datetime.strftime("%Y-%m-%d_%H-%M")
    return formatted_datetime

def plotDeviation(TsRSpt,CommsRate):
    """
    Plots the deviation of the measured reception times from the expected reception times.
    """

    plt.figure(figsize=(10, 5))
    TsRSpt_meas_array = np.array(TsRSpt)
    start=round(TsRSpt_meas_array[0], 3)            # Reception time rounded to ms: e.g. 1718103988.895

    # Create an array of expected reception times for the meas packet
    TsRSpr_meas_exp_array = np.zeros((len(TsRSpt_meas_array)))
    for x in range(0, len(TsRSpt_meas_array)):
        TsRSpr_meas_exp_array[x]=start + (1/CommsRate) * x

    np.set_printoptions(suppress = True, formatter = {'float_kind':'{:0.6f}'.format},threshold=20) #set np arrays to show 6 decimal places and if nr of items are more than 20, show firt and last 3 items
  
    print(f"Timestamp received array:  \n {np.array(TsRSpt_meas_array)}"+"\n")
    print(f"Timestamp received expected @{CommsRate}Hz array:\n {np.array(TsRSpr_meas_exp_array)}"+"\n")

    # Calculate the deviation between the measured and expected reception times
    TsRSpr_meas_delta_array=np.subtract(TsRSpt_meas_array, TsRSpr_meas_exp_array)
    
    print(f"TsRSpr delta array:\n {np.array(TsRSpr_meas_delta_array)}")
    print("")
 
    plt.title("Reception time distribution from expected reception")
    plt.xlabel("Deviation")
    plt.ylabel("Nr of Samples")
    plt.hist(TsRSpr_meas_delta_array, 75)
    if output_plot:
        plt.savefig(output_plot+ f"reception-plot_{getCurrentFormattedDatetime()}.png")
        print(f"Plot reception saved in path: {output_plot} with name: reception-plot_{getCurrentFormattedDatetime()}.png")

    x=np.arange(0, len(TsRSpr_meas_exp_array), 1)
    plt.figure(figsize=(10, 5))
    plt.plot(x, TsRSpr_meas_delta_array[0:len(TsRSpr_meas_delta_array)], 'b.', markersize=5)
    plt.title("Deviation from expected reception")
    plt.xlabel("Samples")
    plt.ylabel("Deviation")
    
    if output_plot:
        plt.savefig( output_plot+ f"deviation-plot_{getCurrentFormattedDatetime()}.png")
        print(f"Plot deviation saved in path: {output_plot} with name: deviation-plot_{getCurrentFormattedDatetime()}.png")
        print("")

    plt.show(block=True)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Postprocessing of the IF results')
    parser.add_argument('-p', type=str, required=True, help = 'pcap file to process',)
    parser.add_argument('-t', type=int, required=True, help = 'topicID to be analyzed')
    parser.add_argument('-r', type=int, required=True, help = 'Rate of Communication in Hz.')
    parser.add_argument('-o', type=str, required=False, help = 'Export PNG image with plots. Note that folder MUST be previously created!')
    parser.add_argument('-l', type=str,nargs='+', required=True, help = 'List of IPs')
    
    args = parser.parse_args()

    pcap_file = args.p
    topic_id = args.t
    output_plot = args.o
    rate = args.r
    ipFilter=args.l

    TsRSpt=[]
    TsMSpt=[]

    print(" ")
    print(f"PCAP file: {pcap_file}")
    print(f"Topic ID: {topic_id}")
    print(f"Rate: {rate}Hz")
    print(" ")

    pp = postp()
    
    #ipFilter= ['239.128.5.11','239.128.5.12'] # For m5 LIH

    # TODO: Use process function or processCapturedPackets ??
    numFrames_meas = pp.processCapturedPackets(TsRSpt,TsMSpt, pcap_file, topic_id,ipFilter)
    inboundLatency =   np.array(TsRSpt)- np.array(TsMSpt)
    row=pp.getStats(inboundLatency, 'Measurement Inbound Latency')
    pp.printStats([row])
    print(" ")
    
    # Call the plotDeviation function to display the plot
    plotDeviation(TsRSpt,rate)
