#!/usr/bin/env python3
from matplotlib import pyplot as plt
import numpy as np
import os.path
from os import path
import sys
import pdfkit
sys.path.append('/home/lanforge/.local/lib/python3.6/site-packages')
def report_banner(date):
    banner_data = """
                   
                    
                    
                    
                    
                    LANforge Report                        
                    
                    FTP Test 
                    
                    
                    
                 """
    return str(banner_data)
def test_objective(objective= 'This FTP Test is used to "Verify that N clients connected on Specified band and can simultaneously download some amount of file from FTP server and measuring the time taken by client to Download/Upload the file."'):
    test_objective = """
                    
                    Objective
 
                    """ + str(objective) + """
                    
                    """
    return str(test_objective)
def test_setup_information(test_setup_data=None):
    if test_setup_data is None:
        return None
    else:
        var = ""
        for i in test_setup_data:
            var = var + "| " + i + " | " + str(test_setup_data[i]) + " | 
"
    setup_information = """
                        
                        
                            
                              | Test Setup Information | 
                            
                              | Device Under Test |  | 
                        
                        
                        """
    return str(setup_information)
def pass_fail_description(data=" This Table will give Pass/Fail results. "):
    pass_fail_info = """
                        
                        PASS/FAIL Results
 
                        """ + str(data) + """
                        
                    """
    return str(pass_fail_info)
def download_upload_time_description(data=" This Table will FTP Download/Upload Time of Clients."):
    download_upload_time= """
                    
                    File Download/Upload Time (sec)
 
                    """ + str(data) + """
                    
                """
    return str(download_upload_time)
def add_pass_fail_table(result_data, row_head_list, col_head_list):
    var_row = ""
    for row in col_head_list:
        var_row = var_row + " | " + str(row) + ""
    list_data = []
    dict_data = {}
    bands = result_data[1]["bands"]
    file_sizes = result_data[1]["file_sizes"]
    directions = result_data[1]["directions"]
    for b in bands:
        final_data = ""
        for size in file_sizes:
            for d in directions:
                for data in result_data.values():
                    if data["band"] == b and data["direction"] == d and data["file_size"] == size:
                        if data["result"] == "Pass":
                            final_data = final_data + " | Pass"
                        elif data["result"] == "Fail":
                            final_data = final_data + " | Fail"
        list_data.append(final_data)
    #print(list_data)
    j = 0
    for i in row_head_list:
        dict_data[i] = list_data[j]
        j = j + 1
    #print(dict_data)
    var_col = ""
    for col in row_head_list:
        var_col = var_col + " | | " + str(col) + "" + str(
            dict_data[col]) + " | 
"
    pass_fail_table = """
                      
                      
                        
                          
                              """ + str(var_row) + """
                          
                          """ + str(var_col) + """
                       
                      
                      
                      """
    return pass_fail_table
def download_upload_time_table(result_data, row_head_list, col_head_list):
    var_row = ""
    for row in col_head_list:
        var_row = var_row + " | " + str(row) + ""
    list_data = []
    dict_data = {}
    bands = result_data[1]["bands"]
    file_sizes = result_data[1]["file_sizes"]
    directions = result_data[1]["directions"]
    for b in bands:
        final_data = ""
        for size in file_sizes:
            for d in directions:
                for data in result_data.values():
                    data_time = data['time']
                    if data_time.count(0) == 0:
                        Min = min(data_time)
                        Max = max(data_time)
                        Sum = int(sum(data_time))
                        Len = len(data_time)
                        Avg = round(Sum / Len,2)
                    elif data_time.count(0) == len(data_time):
                        Min = "-"
                        Max = "-"
                        Avg = "-"
                    else:
                        data_time = [i for i in data_time if i != 0]
                        Min = min(data_time)
                        Max = max(data_time)
                        Sum = int(sum(data_time))
                        Len = len(data_time)
                        Avg = round(Sum / Len,2)
                    string_data = "Min=" + str(Min) + ",Max=" + str(Max) + ",Avg=" + str(Avg) + " (sec)"
                    if data["band"] == b and data["direction"] == d and data["file_size"] == size:
                        final_data = final_data + """ | """ + string_data + """"""
        list_data.append(final_data)
    #print(list_data)
    j = 0
    for i in row_head_list:
        dict_data[i] = list_data[j]
        j = j + 1
    #print(dict_data)
    var_col = ""
    for col in row_head_list:
        var_col = var_col + " | | " + str(col) + "" + str(
            dict_data[col]) + " | 
"
    download_upload_table = """
                        
                        
                          
                            
                                """ + str(var_row) + """
                            
                            """ + str(var_col) + """
                         
                        
                        
                        """
    return download_upload_table
def graph_html(graph_path="",graph_name="",graph_description=""):
    graph_html_obj = """
    """ +graph_name+ """
 
    """ +graph_description+ """
      ![]() 
    
    """
    return str(graph_html_obj)
def bar_plot(ax,x_axis, data, colors=None, total_width=0.8, single_width=1, legend=True):
    # Check if colors where provided, otherwhise use the default color cycle
    if colors is None:
        colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
    # Number of bars per group
    n_bars = len(data)
    # The width of a single bar
    bar_width = total_width / n_bars
    # List containing handles for the drawn bars, used for the legend
    bars = []
    # Iterate over all data
    for i, (name, values) in enumerate(data.items()):
        # The offset in x direction of that bar
        x_offset = (i - n_bars / 2) * bar_width + bar_width / 2
        # Draw a bar for every value of that type
        for x, y in enumerate(values):
            bar = ax.bar(x + x_offset, y, width=bar_width * single_width, color=colors[i % len(colors)])
        # Add a handle to the last drawn bar, which we'll need for the legend
        bars.append(bar[0])
    # Draw legend if we need
    if legend:
        ax.legend(bars, data.keys(),bbox_to_anchor=(1.1,1.05),loc='upper right')
    ax.set_ylabel('Time in seconds')
    ax.set_xlabel("stations")
    x_data = x_axis
    idx = np.asarray([i for i in range(len(x_data))])
    ax.set_xticks(idx)
    ax.set_xticklabels(x_data)
def generate_graph(result_data, x_axis,band,size,graph_path):
    # bands = result_data[1]["bands"]
    # file_sizes = result_data[1]["file_sizes"]
    num_stations = result_data[1]["num_stations"]
    # for b in bands:
    #     for size in file_sizes:
    dict_of_graph = {}
    color = []
    graph_name = ""
    graph_description=""
    count = 0
    for data in result_data.values():
        if data["band"] == band and data["file_size"] == size and data["direction"] == "Download":
            dict_of_graph["Download"] = data["time"]
            color.append("Orange")
            graph_name = "File size "+ size +" " + str(num_stations) + " Clients " +band+ "-File Download Times(secs)"
            graph_description =  "Out of "+ str(data["num_stations"])+ " clients, "+ str(data["num_stations"] - data["time"].count(0))+ " are able to download " + "within " + str(data["duration"]) + " min."
            count = count + 1
        if data["band"] == band and data["file_size"] == size and data["direction"] == "Upload":
            dict_of_graph["Upload"] = data["time"]
            color.append("Blue")
            graph_name = "File size "+ size +" " + str(num_stations) + " Clients " +band+ "-File Upload Times(secs)"
            graph_description = graph_description + "Out of " + str(data["num_stations"]) + " clients, " + str(
                data["num_stations"] - data["time"].count(0)) + " are able to upload " + "within " +str(data["duration"]) + " min."
            count = count + 1
    if count == 2:
        graph_name = "File size "+ size +" " + str(num_stations) + " Clients " +band+ "-File Download and Upload Times(secs)"
    if len(dict_of_graph) != 0:
        fig, ax = plt.subplots()
        bar_plot(ax, x_axis, dict_of_graph, total_width=.8, single_width=.9, colors=color)
        my_dpi = 96
        figure = plt.gcf()  # get current figure
        figure.set_size_inches(18, 6)
        # when saving, specify the DPI
        plt.savefig(graph_path + "/image"+band+size+".png", dpi=my_dpi)
        return str(graph_html(graph_path + "/image"+band+size+".png", graph_name,graph_description))
    else:
        return ""
def input_setup_info_table(input_setup_info=None):
    if input_setup_info is None:
        return None
    else:
        var = ""
        for i in input_setup_info:
            var = var + "| " + i + " | " + str(input_setup_info[i]) + " | 
"
    setup_information = """
                        
                        
                            
                              | Input Setup Information | 
                            
                              | Information |  | 
                        
                        
                        """
    return str(setup_information)
def generate_report(result_data=None,
                    date=None,
                    test_setup_info={},
                    input_setup_info={},
                    graph_path="/home/lanforge/html-reports/FTP-Test"):
    # Need to pass this to test_setup_information()
    input_setup_info = input_setup_info
    test_setup_data = test_setup_info
    x_axis = []
    num_stations = result_data[1]["num_stations"]
    for i in range(1, num_stations + 1, 1):
        x_axis.append(i)
    column_head = []
    rows_head = []
    bands = result_data[1]["bands"]
    file_sizes = result_data[1]["file_sizes"]
    directions = result_data[1]["directions"]
    for size in file_sizes:
        for direction in directions:
            column_head.append(size + " " + direction)
    for band in bands:
        if band != "Both":
            rows_head.append(str(num_stations) + " Clients-" + band)
        else:
            rows_head.append(str(num_stations // 2) + "+" + str(num_stations // 2) + " Clients-2.4G+5G")
    reports_root = graph_path + "/" + str(date)
    if path.exists(graph_path):
        os.mkdir(reports_root)
        print("Reports Root is Created")
    else:
        os.mkdir(graph_path)
        os.mkdir(reports_root)
        print("Reports Root is created")
    print("Generating Reports in : ", reports_root)
    html_report = report_banner(date) + \
                  test_setup_information(test_setup_data) + \
                  test_objective() + \
                  pass_fail_description() + \
                  add_pass_fail_table(result_data, rows_head, column_head) + \
                  download_upload_time_description() + \
                  download_upload_time_table(result_data, rows_head, column_head)
    for b in bands:
        for size in file_sizes:
            html_report = html_report + \
                          generate_graph(result_data, x_axis, b, size, graph_path=reports_root)
    html_report = html_report + input_setup_info_table(input_setup_info)
    # write the html_report into a file in /home/lanforge/html_reports in a directory named FTP-Test and html_report name should be having a timesnap with it
    f = open(reports_root + "/report.html", "a")
    # f = open("report.html", "a")
    f.write(html_report)
    f.close()
    # write logic to generate pdf here
    pdfkit.from_file(reports_root + "/report.html", reports_root + "/report.pdf")
# test blocks from here
if __name__ == '__main__':
    generate_report()