#!/usr/bin/env python
# coding: utf-8

 #Import Libraries

from semantic_functions import *
number_of_run=sys.argv[-1]
class Process(multiprocessing.Process): 
    def __init__(self, id): 
        super(Process, self).__init__() 
        self.id = id
  
    def run(self): 
        time.sleep(1) 
        print("I'm the process with id: {}".format(self.id)) 

class SFDI_artist:
    def __init__(self):
        self.number_of_agents=[]
        self.best_cost=[]
        self.best_game=[]
    def update(self,agents,cost,best_game):
        if agents not in self.number_of_agents:
            self.number_of_agents.append(agents)
            self.best_cost.append(cost)
            self.best_game.append(best_game)
        else:
            if cost>self.best_cost[self.number_of_agents.index(agents)]:
                self.best_cost[self.number_of_agents.index(agents)]=cost
    def create_distribution(self):
        plt.figure()
        plt.plot(self.number_of_agents,self.best_cost,'r-')
        plt.plot(self.number_of_agents,self.best_cost,'bx')
        plt.xlabel("N [Number of agents]")
        plt.ylabel("Maximum value of cost function")
        plt.xticks(self.number_of_agents)
        plt.yticks(np.arange(10, 18, 1))
        plt.grid()
        plt.savefig('SFDI_Results/performance.png')
        print("The best games were",self.best_game)

if __name__ == '__main__':
    path="Excel_sheets/"
    ascii_banner = pyfiglet.figlet_format("Modular-ready marine vessels")
    print(ascii_banner)
    print("===================")
    print ("Develloped by:")
    print("===================")
    print ("Jesper Zwaginga -TUD")
    print ("Nikos Kougiatsos -TUD \n")
    myartist=SFDI_artist()

    #Open all relevant datasheets from database

    system_functions = pd.read_excel(path+"System_database_2.xlsx", sheet_name="sysfunction").replace(np.nan,'None') 
    system_input = create_sheet(system_functions, "Input","System")
    system_output = create_sheet(system_functions, "Output","System")
    system_distr = create_sheet(system_functions, "Distribution","System")
    system_group=create_sheet(system_functions, "Group","System")
    edgelist = []
    mediumlist = [] 
    hold_test = []
    in_out_dict = start_dict()
    external_graph = defaultdict(list)
    todolist = pd.Series(system_functions.System.loc[8])
    in_out_dict, system_list, external_graph, hold_test = onesystem(system_input,system_output, todolist.loc[0], in_out_dict, external_graph, hold_test,system_distr,edgelist,mediumlist)

    # Run for all systems
    edgelist = []
    mediumlist = [] 
    hold_test = [] # without holdtest external graph isnt saved
    in_out_dict = defaultdict(list)
    external_graph = defaultdict(list)
    todolist = pd.Series(system_functions.System.loc[8])
    in_out_dict= runthrough(system_input, system_output, system_distr, todolist, in_out_dict, external_graph, hold_test,edgelist,mediumlist,flag='s')     
    plot_graph(in_out_dict['mediumlist'], in_out_dict['edgelist'],"network_graph.png")

    ain_out_dict, automation_graph, automation_dataframe =physical_connect(in_out_dict,path)
    print(automation_dataframe)
    plot_automation_graph(automation_graph,automation_dataframe,"network_graph_hautomation.png")
    ain_out_dict, diagnosis_graph, diagnosis_dataframe =fault_generation(ain_out_dict)
    print(diagnosis_dataframe)
    plot_automation_graph(diagnosis_graph,diagnosis_dataframe,"network_graph_diagnosis.png")
    monitoring_interconnections=np.array([[0,1,1,1,0],[0,0,1,1,1],[0,0,0,1,0],[0,1,1,0,0],[0,1,0,0,0]])
    ain_out_dict, automation_graph, automation_dataframe =cyber_connect(ain_out_dict,path)
    print(automation_dataframe)
    automation_dataframe.to_excel("Semantic_database.xlsx")
    plot_automation_graph(automation_graph,automation_dataframe,"network_graph_full.png")
    for run in range(1,int(float(number_of_run))+1):
        gsa(ain_out_dict,run)
    for N in range(0,5):
        best_cost=0
        game_encountered=0
        for run in range(1,int(float(number_of_run))+1):
            df=pd.read_excel('SFDI_Results/'+str(N+1)+'_Agent/game_'+str(run)+'_log.xlsx')
            if (best_cost<df["Cost"].iloc[-1]):
                best_cost=df["Cost"].iloc[-1]
                game_encountered=run
            else:
                pass
        myartist.update(N+1,best_cost,game_encountered)
    myartist.create_distribution()
    print("=========================================================================================================================================")
    print("Greedy algorithm has converged to the solution!You can find the output figure at SFDI_Results :)")
    print("=========================================================================================================================================")


    #
    #FSM_generator(ain_out_dict)


    # #### Step 3: Semantic matching
    # 

    # In[9]:


    # Here we create the feasible closed-loop architectures
'''
    class closed_loop_system:
        def __init__(self):
            self.controllers=[]
            self.feedback_sensors=[]
            self.system=[]
            self.monitoring=None
            self.associated_sensors=None 
            self.configurations=[]
            self.check_loop=np.zeros((3,1))
        def check_loop_reset(self):
            self.check_loop=np.zeros((3,1))
        def find_one(self,graph):
            for controller in graph.vs["name"]:
                if 'Controller' in controller:
                    self.check_loop[0]=1 
                    graph_paths_in=graph.get_all_simple_paths(controller,graph.neighbors(controller),mode="in")
                    for path in graph_paths_in:
                        for node in path:
                            name=graph.vs["name"][node]
                            if ((path[1]==node) and ("sensor" in name)):
                                self.check_loop[1]=1 
                            if (((path[-1]==node)) and ("sensor" not in name) and ("Controller" not in name) and ("Monitoring" not in name)):
                                self.check_loop[-1]=1
                            if self.check_loop.tolist()==[1,1,1]:
                                self.controllers.append(controller)
                                self.feedback_sensors.append(graph.vs["name"][path[1]])
                                self.system.append(graph.vs["name"][path[-1]])
                                self.configurations.append[path]
                            print(name)
                        print(self.check_loop.tolist())
                        print("===============")
                        self.check_loop_reset()
                    #graph_path_out=graph.get_all_simple_paths(name,graph.neighbors(name),mode="out")
                    #self.feedback_sensors.append(list(set([graph.vs["name"][l[1]] for l in graph_path_in])))
                    #self.system.append(list(set([graph.vs["name"][l[1]] for l in graph_path_out if (("Monitoring" not in graph.vs["name"][l[1]]) and ("virtual" not in graph.vs["name"][l[1]]))])))
            print(self.controllers)
            print(self.feedback_sensors)
            print(self.system)

    cl=closed_loop_system()
    cl.find_one(automation_graph)


# #### Step 4: Semantic Reasoning
# 

# In[10]:


# Here we determine which closed loop to use based on performance and operational criteria


# #### Step 5: Extra visuals
# 

# In[ ]:
'''



