#Misc util functions
import json
import requests
import datetime
from processing.similarityFiles.miscFunctions import *
from db.repository import Repository
repo = Repository()

def outputFileLayerFunction(layerDict,limitNrNodes,limitNrCluster,runId):
    ''' Writes the layerDict data to a JSON file.

    :param Dict{string: Layer} layerDict: Object which contains Data about the Layers, Clusters and Nodes

    :param int limitNrNodes: How many nodes are contained in layerDict. Used in creating the name of the File

    :param int limitNrCluster: How many clusters are contained in layerDict. Used in creating the name of the File

    '''  

    layerJSON = convertLayerDictToJSON(layerDict,runId)
    outputJSON = json.dumps(layerJSON, default=lambda o: o.__dict__, indent=4)
            
    try:
        with open('resultLayerDictN'+str(limitNrNodes)+'C'+str(limitNrCluster)+'.json', 'w') as outfile:
            outfile.write(outputJSON)
    except ValueError:
        print("Error occured when writing the resultLayerDict file")



def outputFileSimilFunction(similarityDict,limitNrNodes,limitNrCluster,runId):

    ''' Writes the similarityDict data to a JSON file.

    :param Dict{(cluster_label1, cluster_label2): Dict{layername: value}} similarityDict: Object which contains Data about the similarity between the clusters, Clusters and Nodes

    :param int limitNrNodes: How many nodes are contained in layerDict. Used in creating the name of the File

    :param int limitNrCluster: How many clusters are contained in layerDict. Used in creating the name of the File

    '''  
    
    similJSON = convertSimilarityDictToJSON(similarityDict,runId)
    outputJSON = json.dumps(similJSON, default=lambda o: o.__dict__, indent=4)

    try: 
        with open('resultSimilarityDictN'+str(limitNrNodes)+'C'+str(limitNrCluster)+'.json', 'w') as outfile2:
            outfile2.write(outputJSON)
    except ValueError:
        print("Error occured when writing the resultSimilarityDict file")

def outputFileTimeFunction(timelist,limitNrNodes,limitNrCluster,runId):
    ''' Writes execution time to a file.

    :param List[datetime] timelist: Contains timestamps about the execution time of functions and the program.

    :param int limitNrNodes: How many nodes are considered. Used in creating the name of the File

    :param int limitNrCluster: How many clusters are considered. Used in creating the name of the File

    '''  

    stringToWrite = "StartTime: "+ str(timelist[0])
    stringToWrite += "\nFinishTime: " + str((timelist[3])) +"\n"
    stringToWrite += "\nPopulateWithNewNodes: " + str((timelist[1]-timelist[0]).total_seconds())
    stringToWrite += "\nCalculateWeights: " + str((timelist[2]-timelist[1]).total_seconds())
    stringToWrite += "\nCalculateSimilarity: " + str((timelist[3]-timelist[2]).total_seconds())
    stringToWrite += "\nTotalTime: " + str((timelist[3]-timelist[0]).total_seconds())
    stringToWrite += "\nRunId: " +str(runId)
    

    #aux = str(timelist[0]) + " :PopulateWithNewNodes\n"+ str(timelist[1]) +  " :CalculateWeights\n" + str(timelist[2]) + " :CalculateSimilarity\n"+   str(timelist[3]) + " :Finish" 
    try:
        with open('resultTimeExecN'+str(limitNrNodes)+'C'+str(limitNrCluster)+'.txt', 'w') as outfile3:
            outfile3.write(stringToWrite)
    except ValueError:
        print("Error occured when writing the resultTimeExec file")


def outputMongoConnClustDict(inputDict,runId):

    ''' Stores connected_clusters in the database.

    :param Dict() inputDict: Contains the data to insert

    :param string runId: Id of the Run 

    '''  

    #inputDict["Timestamp"] = str(datetime.datetime.now())
    
    add_conn_clusters(inputDict,runId)

def outputMongoSimilarity(inputDict,runId):
    ''' Stores cluster_similarity in the database.

    :param Dict() inputDict: Contains the data to insert

    :param string runId: Id of the Run 

    ''' 
    add_similarity(inputDict,runId)

def add_connected_run():

    '''
        Inserts Run with current Time into the DB
        
        :returns: Returns the _id of the connected_run entry in the DB
    
        :rtype: string
    '''    

    currentTime = datetime.datetime.now()
    runDict = {"Datetime" : str(currentTime)}
    inserted_result = repo.add_connected_run(runDict)
    return str(inserted_result.inserted_id)

def add_conn_clusters(inputDict,runId):
    ''' Stores connected_clusters in the database.

    :param Dict() inputDict: Contains the data to insert

    :param string runId: Id of the Run 

    ''' 
    
    outputJSON = convertLayerDictToJSON(inputDict,runId)
    repo.add_connected_clusters(outputJSON)

def add_similarity(inputDict,runId):
    ''' Stores cluster_similarity in the database.

    :param Dict() inputDict: Contains the data to insert

    :param string runId: Id of the Run 

    ''' 

    outputJSON = convertSimilarityDictToJSON(inputDict,runId)
    repo.add_similarity(outputJSON)