import os, subprocess, shutil
from rdflib import XSD, Graph, BNode
from rdflib.namespace import RDFS
from rdflib import ConjunctiveGraph, URIRef, RDFS, RDF, Namespace, Literal
from reqman.apps.reqtool.rest_api.services.parse_ontologies import *

#HERE
#Ontology_file = "../../Ontologies/Autonomy_v1.ttl"
#Ontology_file = "../../Ontologies/2022_AOCS.ttl"

list_of_inference_metrics = ["IncompleteRequirement", "AmbiguousRequirement",
"InconsistentRequirement","NoisyRequirement","OpaqueRequirement","RedundantRequirement"]

info_metric = ["isMissingConcept", "isMissingInstanceOf", "isMissingProducer", "isMissingState", "hasAmbiguousConcept", "hasAmbiguousConcept2",
"hasNoisyConcept", "hasOpaqueConcept", "isInconsistentTo"]

def getclassofprefix(prefix, ontology_file):
    return(findclassofprefix(prefix, ontology_file))

def getclassofmain(main, ontology_file):
    return(findclassofmain(main, ontology_file))

def getinstancefile(data, g):
    datam = data.split(":")
    out_list = get_file_and_instances('SAO#'+ datam[0].strip(), g)
    for j in range(0,(len(out_list)-1),2):
        if ( datam[len(datam) -2].strip()+' : '+ datam[len(datam) -1].strip() ) in out_list[j]:
            splitter = out_list[j].split(" : ")
            instance_file = out_list[j+1] 
            break
    return instance_file, splitter


def inferencing(ontfile, project, boilerlate, prefix, main, suffix):
    metrics = {}
    listofboil = []
    listofprefix = []
    listofmain = []
    listofsuffix = []
    for i in boilerlate:
            listofboil.append(list(i.values()))
            #print(list(i.values('title'))[0]['title'])
            metrics[list(i.values('title'))[0]['title']] = []
    for i in prefix:
            listofprefix.append(list(i.values()))
    for i in main:
            listofmain.append(list(i.values()))
    for i in suffix:
            listofsuffix.append(list(i.values()))
    #findclassofmain(listofmain)
    ontology_with_new_req = exportboiltottl(ontfile, project, listofprefix, listofboil, listofmain, listofsuffix)
    infer_result = shacl(ontology_with_new_req)
    ontology_with_new_req_and_infer = ontology_with_new_req #+"infer.ttl"
    #find in which metrics the requirements belongs e.g. title:REQ-1 is only an Incomplete req (and Ambiguous req), 
    # so -> 'REQ-1' : [Incomplete] ('REQ-1' : [Incomplete, Ambiguous])
    for met in infer_result:
        for title in metrics:
            if title in infer_result[met]:
                metrics[title].append(met)
    metrics.update(infer_result)
    return (metrics, ontology_with_new_req_and_infer)


def exportboiltottl(ontfile,project, prefix, boilerplate, main, suffix):
    ''' Export boilerplate to ttl file and return the file path'''
    per_instances = URIRef("http://delab.csd.auth.gr/ontologies/2018/RDO-instances#")
    rdo = URIRef("http://delab.csd.auth.gr/ontologies/2018/RDO#")
    sao = URIRef("http://delab.csd.auth.gr/ontologies/2018/SAO#")
    rbo = URIRef("http://delab.csd.auth.gr/ontologies/2018/RBO#")
    lo = URIRef("http://delab.csd.auth.gr/ontologies/2018/LO-instances#")
    g = Graph()
    #find the ontology to load
    file_name = project.replace('/', '')
    save_path = "../../Ontologies/"+file_name+"/"
    if (os.path.exists("../../Ontologies/"+file_name+"/") == False):
        os.mkdir("../../Ontologies/"+file_name)
        completeName = os.path.join(save_path, file_name)
        g.load('../../Ontologies/'+ontfile, format="turtle")
    else :
        g.load(ontfile, format="turtle")
    #print(ontfile)
    #remove the requirements from the RDO-instances
    #previous_req = URIRef("http://delab.csd.auth.gr/ontologies/2018/RDO-instances#")
    #g.remove((previous_req, None, None))
    for i in range(len(boilerplate)):
        title = boilerplate[i][0]['title']
        g.add((per_instances + title, RDF.type, rdo + 'Requirement'))
        try:
            if (boilerplate[i][0]['has_prefix'] == True): #If the requirement has Prefix
                g.add((per_instances + title, rdo + 'hasPrefix', per_instances+(title+"_"+ prefix[i][0]['simple_prefix'])))
                g.add((per_instances+(title+"_"+ prefix[i][0]['simple_prefix']), RDF.type, rbo + prefix[i][0]['simple_prefix']))
                prefixsub_splitter = prefix[i][0]['system_fun_item'].split(" : ")
                prefix_attr_splitter = prefix[i][0]['item_function_flow_statevalue'].split(" : ")
                prefix_verb_splitter = prefix[i][0]['state_or_verb'].split(" : ")
                if (prefix_verb_splitter[0] == 'State'):
                    g.add( (per_instances+(title+"_"+ prefix[i][0]['simple_prefix']), rbo+"isRelatedToLogicalExpression", (per_instances+("SystemStateValueContraint_"+title))))
                    g.add((per_instances+("SystemStateValueContraint_"+title), RDF.type, (per_instances+("SystemStateValueContraint"))))
                    g.add((per_instances+("SystemStateValueContraint_"+title), rbo+"isRelatedToState", rbo + prefix_verb_splitter[len(prefix_verb_splitter)-1].strip()))
                    g.add((per_instances+("SystemStateValueContraint_"+title), rbo+"isRelatedToSystem", rbo + prefixsub_splitter[len(prefixsub_splitter)-1].strip()))
                    g.add((per_instances+("SystemStateValueContraint_"+title), rbo+"isRelatedToStateValue", rbo + prefix_attr_splitter[len(prefix_attr_splitter)-1].strip()))
                elif(prefix_attr_splitter[0]=="StateValue"):
                    g.add( (per_instances+(title+"_"+ prefix[i][0]['simple_prefix']), rbo+"isRelatedToLogicalExpression", (per_instances+("ItemStateValueContraint_"+title))))
                    g.add((per_instances+("ItemStateValueContraint_"+title), RDF.type, (per_instances+("ItemStateValueContraint"))))
                    g.add((per_instances+("ItemStateValueContraint_"+title), rbo+"isRelatedToTraversingConcept", rbo + prefixsub_splitter[len(prefixsub_splitter)-1].strip()))
                    g.add((per_instances+("ItemStateValueContraint_"+title), rbo+"isRelatedToStateValue", rbo + prefix_attr_splitter[len(prefix_attr_splitter)-1].strip()))
                else:
                    g.add((per_instances+(title+"_"+ prefix[i][0]['simple_prefix']), rbo+"isRelatedToOccuringFunctionality", per_instances+(prefix_verb_splitter[0]+"OccuringFunctionality"+title)))
                    g.add((per_instances+(prefix_verb_splitter[0]+"OccuringFunctionality"+title), RDF.type, (per_instances+(prefix_verb_splitter[0]+"OccuringFunctionality"))))
                    g.add((per_instances+(prefix_verb_splitter[0]+"OccuringFunctionality"+title), rbo+"isRelatedToAction", lo + prefix_verb_splitter[len(prefix_verb_splitter)-1].strip()))
                    g.add((per_instances+(prefix_verb_splitter[0]+"OccuringFunctionality"+title), rbo+"isRelatedToStimulus", rbo + prefixsub_splitter[len(prefixsub_splitter)-1].strip()))
                    if(prefix_attr_splitter[0]=='Item'):
                        g.add((per_instances+(prefix_verb_splitter[0]+"OccuringFunctionality"+title), rbo+"isRelatedToTraversingConcept", rbo + prefix_attr_splitter[len(prefix_attr_splitter)-1].strip()))
                    elif(prefix_attr_splitter[0]=='Function'):
                        g.add((per_instances+(prefix_verb_splitter[0]+"OccuringFunctionality"+title), rbo+"isRelatedToFunction", rbo + prefix_attr_splitter[len(prefix_attr_splitter)-1].strip()))
        except:
            raise APIException("The instances in Prefix of Boilerplate "+title+" are not exist in the Ontology")
        #try:
        if (boilerplate[i][0]['has_main'] == True): #If the requirement has Main
            g.add((per_instances + title, rdo + 'hasMain', per_instances+(title+"_"+ main[i][0]['main_choices'])))
            g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), RDF.type, rbo + main[i][0]['main_choices']))
            if main[i][0]['sys_fun_inter'] != "":
                #print(main[i][0]['sys_fun_inter'])
                instance_file, splitter_1 = getinstancefile(main[i][0]['sys_fun_inter'], g)  
                g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), rbo+"isRelatedToSubject", URIRef(str(instance_file))+"#"+ str(splitter_1[len(splitter_1) -1])))
            if main[i][0]['verb'] != "":
                mainverb = main[i][0]['verb'].split(':')
                g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), rbo+"isRelatedToAction", lo + mainverb[1].strip()))
            #mainmodel=["flow_function_interface_item_system_state_stateset", "state_item_before_verb", "statevalue_before_verb", "statevalue_system_connection_stateset"]
            mainmodel=["flow_function_interface_item_system_state_stateset", "statevalue_system_connection_stateset"]
            for j in mainmodel:
                if(main[i][0][j] != ""):
                    instance_file, splitter_1 = getinstancefile(main[i][0][j], g)  
                    if ( splitter_1[0] =='Item' or splitter_1[0] =='Flow' ):
                        g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), rbo+"isRelatedToTraversingConcept", URIRef(str(instance_file))+"#"+ str(splitter_1[len(splitter_1) -1])))
                    else :
                        g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), rbo+"isRelatedTo"+splitter_1[0], URIRef(str(instance_file))+"#"+ str(splitter_1[len(splitter_1) -1])))
            mainbeforeverbmodel=["state_item_before_verb", "statevalue_before_verb"]
            for j in mainbeforeverbmodel:
                if main[i][0][j] != "":
                    instance_file, splitter_1 = getinstancefile(main[i][0][j], g)  
                    g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), rbo+"isRelatedToSubject"+splitter_1[0], URIRef(str(instance_file))+"#"+ str(splitter_1[len(splitter_1) -1])))
            if main[i][0]['quantifier'] != "":
                quantimain= main[i][0]['quantifier'].split(':')
                if(quantimain[len(quantimain)-2].strip() == "NonNumericalAffirmative"):
                    g.add((per_instances+(title+ "_Quantifier" ), rbo+"isRelatedToQuantifier", lo+ (quantimain[len(quantimain)-1].strip())))
                elif(quantimain[len(quantimain)-2].strip() == "Negative"):
                    g.add((per_instances+(title+ "_Quantifier" ), rbo+"isRelatedToQuantifier", lo+ (quantimain[len(quantimain)-1].strip())))
                elif ( quantimain[len(quantimain)-2].strip() == "ClosedInterval"):
                    g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), rbo+"isRelatedToQuantifier", (per_instances+(title+ "_Quantifier" ))))
                    g.add((per_instances+(title+ "_Quantifier" ), RDF.type, rbo+"ClosedInterval"))
                    g.add((per_instances+(title+ "_Quantifier" ), rbo+"isRelatedToNumericalQuantifier", lo+quantimain[len(quantimain)-1].strip()))
                    #isRelatedToNumerical
                    g.add((per_instances+(title+ "_Quantifier" ), rbo+"isRelatedToNumerical", per_instances+(title+ "_Quantifier_Numerical")))
                    g.add((per_instances+(title+ "_Quantifier_Numerical"), RDF.type , rbo+"Numerical" ))
                    if(main[i][0]["numerical"] !=""):
                        g.add((per_instances+(title+ "_Quantifier_Numerical"), rbo+"isRelatedToNumber", (Literal(suffix[i][0]["numerical"], datatype=XSD.float)) ))
                    #isRelatedToTimeUnit
                    if(main[i][0]["mumerical_units"]!=""):
                        g.add((per_instances+(title+ "_Quantifier_Numerical"), rbo+"isRelatedToNumberUnit", lo+numunit[len(numunit)-1].strip() ))
                elif(quantimain[len(quantimain)-2].strip() == "NumericalAffirmative"):
                    g.add((per_instances+(title+"_"+ main[i][0]['main_choices']), rbo+"isRelatedToQuantifier", (per_instances+(title+ "_Quantifier" ))))
                    g.add((per_instances+(title+ "_Quantifier" ), RDF.type, rbo+"NumericalAffirmative"))
                    g.add((per_instances+(title+ "_Quantifier" ), rbo+"isRelatedToNumericalQuantifier", lo+quantimain[len(quantimain)-1].strip()))
                    #isRelatedToNumerical
                    g.add((per_instances+(title+ "_Quantifier" ), rbo+"isRelatedToNumerical", per_instances+(title+ "_Quantifier_Numerical")))
                    g.add((per_instances+(title+ "_Quantifier_Numerical"), RDF.type , rbo+"Numerical" ))
                    if(main[i][0]["numerical"] !=""):
                        g.add((per_instances+(title+ "_Quantifier_Numerical"), rbo+"isRelatedToNumber", (Literal(suffix[i][0]["numerical"], datatype=XSD.float)) ))
                    #isRelatedToTimeUnit
                    if(main[i][0]["mumerical_units"]!=""):
                        g.add((per_instances+(title+ "_Quantifier_Numerical"), rbo+"isRelatedToNumberUnit", lo+numunit[len(numunit)-1].strip() ))
        #except:
        #    raise APIException("The instances in MAIN of Boilerplate "+title+" are not exist in the Ontology")
        try:
            if (boilerplate[i][0]['has_suffix'] == True):
                typesuffix = suffix[i][0]['s_choices'].split(':')
                numunit=suffix[i][0]["mumerical_units"].split(":")
                flowsuf=suffix[i][0]['flow'].split(':')
                if(suffix[i][0]['s_choices']!= ""):
                    if ( typesuffix[len(typesuffix)-2].strip() == "NumericalAffirmative" or typesuffix[len(typesuffix)-2].strip() == "ClosedInterval"): #S1
                        g.add((per_instances + title, rdo + 'hasSuffix', per_instances+(title+"_"+ "S1")))
                        g.add((per_instances+(title+"_"+ "S1"), RDF.type, URIRef(rbo+ "S1")))
                        #create Quantifier instance
                        g.add((per_instances+(title+"_"+ "S1"), rbo+"isRelatedToQuantifier", per_instances+(title+"_"+ "S1"+ "_Quantifier")))
                        if ( typesuffix[len(typesuffix)-2].strip() == "ClosedInterval"):
                            g.add((per_instances+(title+"_"+ "S1"+ "_Quantifier"), RDF.type, rbo+"ClosedInterval"))
                        else:
                            g.add((per_instances+(title+"_"+ "S1"+ "_Quantifier"), RDF.type, rbo+"NumericalAffirmative"))
                        #isRelatedToNumericalQuantifier
                        g.add((per_instances+(title+"_"+ "S1"+ "_Quantifier"), rbo+"isRelatedToNumericalQuantifier", lo+ typesuffix[len(typesuffix)-1].strip()))
                        #isRelatedToNumerical
                        g.add((per_instances+(title+"_"+ "S1"+ "_Quantifier"), rbo+"isRelatedToNumerical", per_instances+(title+"_"+ "S1"+ "_Quantifier_Numerical")))
                        g.add((per_instances+(title+"_"+ "S1"+ "_Quantifier_Numerical"), RDF.type , rbo+"Numerical" ))
                        if(suffix[i][0]["numerical"] !=""):
                            g.add((per_instances+(title+"_"+ "S1"+ "_Quantifier_Numerical"), rbo+"isRelatedToNumber", (Literal(suffix[i][0]["numerical"], datatype=XSD.float)) ))
                        #isRelatedToTimeUnit
                        if(suffix[i][0]["mumerical_units"]!=""):
                            if(numunit[len(numunit)-2].strip() == "TimeUnit"):
                                g.add((per_instances+(title+"_"+ "S1"), rbo+"isRelatedToTimeUnit", lo+numunit[len(numunit)-1].strip()))
                            else:
                            #isRelatedtoNumberUnit e.g kilometers
                                g.add((per_instances+(title+"_"+ "S1"+ "_Quantifier_Numerical"), rbo+"isRelatedToNumberUnit", lo+numunit[len(numunit)-1].strip() ))
                    if ( typesuffix[len(typesuffix)-2].strip() == "EventRelated"): #S2
                        g.add((per_instances + title, rdo + 'hasSuffix', per_instances+(title+"_"+ "S2")))
                        g.add((per_instances+(title+"_"+ "S2"), RDF.type, URIRef(rbo+ "S2")))
                        g.add((per_instances+(title+"_"+ "S2"), rbo+"isRelatedToPreposition", lo+typesuffix[len(typesuffix)-1].strip()))
                        if(suffix[i][0]['flow'] !=""):
                            g.add((per_instances+(title+"_"+ "S2"), rbo+"isRelatedToTraversingConcept", lo+flowsuf[len(flowsuf)-1].strip()))
                    if ( typesuffix[len(typesuffix)-2].strip() == "TimeRangeRelated"): #S3
                        g.add((per_instances + title, rdo + 'hasSuffix', per_instances+(title+"_"+ "S3")))
                        g.add((per_instances+(title+"_"+ "S3"), RDF.type, URIRef(rbo+ "S3")))
                        g.add((per_instances+(title+"_"+ "S3"), rbo+"isRelatedToPreposition", lo+typesuffix[len(typesuffix)-1].strip()))
                        if(suffix[i][0]["numerical"] !=""):
                            g.add((per_instances+(title+"_"+ "S3"), rbo+"isRelatedToNumber", (Literal(suffix[i][0]["numerical"], datatype=XSD.float)) ))
                        if(suffix[i][0]["mumerical_units"]!=""):
                            if(numunit[len(numunit)-2].strip() == "TimeUnit"):
                                g.add((per_instances+(title+"_"+ "S3"), rbo+"isRelatedToTimeUnit", lo+numunit[len(numunit)-1].strip()))
                        if(suffix[i][0]['flow'] !=""):
                            g.add((per_instances+(title+"_"+ "S3"), rbo+"isRelatedToTraversingConcept", lo+flowsuf[len(flowsuf)-1].strip()))
                    if ( typesuffix[len(typesuffix)-2].strip() == "TimeFrameRelated"): #S4
                        g.add((per_instances + title, rdo + 'hasSuffix', per_instances+(title+"_"+ "S4")))
                        g.add((per_instances+(title+"_"+ "S4"), RDF.type, URIRef(rbo+ "S4")))
                        g.add((per_instances+(title+"_"+ "S4"), rbo+"isRelatedToPreposition", lo+typesuffix[len(typesuffix)-1].strip()))
                    if ( typesuffix[len(typesuffix)-2].strip() == "TimeSpaceRelated"): #S5
                        g.add((per_instances + title, rdo + 'hasSuffix', per_instances+(title+"_"+ "S5")))
                        g.add((per_instances+(title+"_"+ "S5"), RDF.type, URIRef(rbo+ "S5")))
                        g.add((per_instances+(title+"_"+ "S5"), rbo+"isRelatedToPreposition", lo+typesuffix[len(typesuffix)-1].strip()))
                    if ( typesuffix[len(typesuffix)-2].strip() == "ExecutionRelated"): #S6
                        g.add((per_instances + title, rdo + 'hasSuffix', per_instances+(title+"_"+ "S6")))
                        g.add((per_instances+(title+"_"+ "S6"), RDF.type, URIRef(rbo+ "S6")))
                        g.add((per_instances+(title+"_"+ "S6"), rbo+"isRelatedToPreposition", lo+typesuffix[len(typesuffix)-1].strip()))
                        if(flowsuf[0].strip() == 'Function'):
                            g.add((per_instances+(title+"_"+ "S3"), rbo+"isRelatedToFunction", lo+flowsuf[len(flowsuf)-1].strip()))
        except:
            raise APIException("The instances in SUFFIX of Boilerplate "+title+" are not exist in the Ontology")
    try : 
        g.serialize(destination=ontfile+'.ttl', format='turtle')
        return (ontfile)
    except:
        g.serialize(destination=save_path+file_name+'.ttl', format='turtle')
        return (save_path+file_name)
    #print(g.serialize(format="turtle").decode("utf-8"))

def shacl(ontotlogy_file):
    metrics_dict = {}
    file1 = ontotlogy_file + ".ttl"
    target = ontotlogy_file+"infer.ttl"
    open(target, 'w').close()
    shutil.copyfile(file1, target)
    final_result = ''
    target1 = target.replace(" ","\ ")
    for i in range(30):
        print(i+1, 'Cycle of inferencing')
        #result = subprocess.check_output(["./reqman/apps/reqtool/rest_api/services/shacl-1.3.2/bin/shaclinfer.sh", "-datafile", target])
        try:
            result = subprocess.check_output("./reqman/apps/reqtool/rest_api/services/shacl-1.4.2/bin/shaclinfer.sh -datafile "+target1+" | grep -v -e 'WARN  OntDocumentManager' -e 'at org.' -e 'org.apache.' -e '@'",shell=True, timeout=360)
        except:
            raise APIException("Problem during the Inferencing")
        if(result==final_result):
            break
        final_result=result
        file_object = open(target, 'a')
        res = str(result,'utf-8')
        file_object.write(res.strip())
        file_object.close()
    
    #need to fiil with all the metrics
    g = Graph()
    gon = Graph()
    g.load(target, format="turtle")
    gon.load(ontotlogy_file, format="turtle")
    req_list=[]
    for inf_metr in list_of_inference_metrics:
        metrics_dict[inf_metr] = []
        p = URIRef("http://delab.csd.auth.gr/ontologies/2018/RDO#"+inf_metr)
        for s, p, o in g.triples((None, RDF.type, p)):
            # e.g IncompleteRequirement': ['Req1', 'Req2']
            get_title = str(s).split("#")
            if get_title[1] not in req_list:
                req_list.append(get_title[1])
            metrics_dict[inf_metr].append(get_title[1])
    
    for inf_metr2 in info_metric:
        #e.g isMissingOfInstance : ['Comment' : '...', {'Req1':['Instance1']}, {'Req2':['Instance2']}]
        metrics_dict[inf_metr2] = []
        p = URIRef("http://delab.csd.auth.gr/ontologies/2018/RDO#"+inf_metr2)
        req_dict={}
        req_dict['Comment'] = ""
        for scom, pcom, ocom in g.triples((p, RDFS.comment, None)):
            req_dict['Comment'] = str(ocom)
        for get_title in  req_list:
            req_dict[get_title]=[]
            s = URIRef("http://delab.csd.auth.gr/ontologies/2018/RDO-instances#"+get_title)
            p = URIRef("http://delab.csd.auth.gr/ontologies/2018/RDO#"+inf_metr2)
            for s1, p1, o1 in g.triples((s, p, None)):
                get_title2 = str(o1).split("#")
                req_dict[get_title].append(get_title2[1])
                req_dict[get_title2[1]]=[]
                for s3, p3, o3 in gon.triples((None, None, o1)):
                    sub=str(s3).split("#")
                    ver=str(p3).split("#")
                    obj=str(o3).split("#")
                    if(len(sub)>1 and  len(ver)>1 and len(obj)>1):
                        req_dict[get_title2[1]].append('<i>'+sub[1]+'</i> <u>'+ ver[1]+'</u> <i>'+obj[1]+'</i>')
                for s3, p3, o3 in gon.triples((o1, None, None)):
                    sub1=str(s3).split("#")
                    ver1=str(p3).split("#")
                    obj1=str(o3).split("#")
                    if(len(sub1)>1 and  len(ver1)>1 and len(obj1)>1):
                        req_dict[get_title2[1]].append('<i>'+sub1[1]+'</i> <u>'+ ver1[1]+'</u> <i>'+obj1[1]+'</i>')

        metrics_dict[inf_metr2].append(req_dict)
    #print(metrics_dict)
    return(metrics_dict)


from rest_framework.exceptions import APIException
'''Find if the Prefix exists in syntax'''
def findclassofprefix(listofprefix, Ontology_file):
    classlist=[]
    currentverb = listofprefix['state_or_verb'].rsplit(' : ', 1)
    currentstate = listofprefix['state_or_verb'].rsplit(' : ')
    currentsubject = listofprefix['system_fun_item']
    currentsubjectspl = listofprefix['system_fun_item'].rsplit(' : ')
    currentattr = listofprefix['item_function_flow_statevalue']
    #Need to be automated
    if (currentstate[0] == "State"):
        if (currentsubjectspl[0] != "System"):
            raise APIException("The Subject must be a System")
    if (currentverb[1] == "is"):
        if (currentsubjectspl[0] == "System"):
            raise APIException("The Subject must be an Item")
    #
    g = Graph()
    g.load(Ontology_file, format="turtle")
    prefix_syntax = get_prefix_syntax(g)
    for prefix in prefix_syntax:
        for inprefix in prefix_syntax[prefix]:
            if (currentverb[1] in prefix_syntax[prefix][inprefix.split("_")[0]+"_Verbs"]) or (currentstate[0] in prefix_syntax[prefix][inprefix.split("_")[0]+"_Verbs"] or currentverb[1] =='is' ):
                if currentsubject.split(":")[0].strip() in prefix_syntax[prefix][inprefix.split("_")[0]+"_Subject"]:
                    if currentattr.split(":")[0].strip()  in prefix_syntax[prefix][inprefix.split("_")[0]+"_Attribute"]:
                        if listofprefix['prefix'] == "If":
                            return "P1"
                        if listofprefix['prefix'] == "As soon as":
                            return "P2"
                        if listofprefix['prefix'] == "As long as":
                            return "P3"
                        if listofprefix['prefix'] == "Once":
                            return "P1"
                        if listofprefix['prefix'] == "Unless":
                            return "P1"
                        return(prefix)
    classlist.append("ERROR")
    return classlist



'''Find if the Main exists in syntax'''
def findclassofmain(listofmain, Ontology_file):
    g = Graph()
    g.load(Ontology_file, format="turtle")
    main_syntax = get_main_sytax_inference(g)
    classlist = []
    for i in range(len(main_syntax)):
        verbsmain =  main_syntax[('M'+str(i+1))]['Verbs']
        subsmain =  main_syntax[('M'+str(i+1))]['Subject']
        attrsmain =  main_syntax[('M'+str(i+1))]['Attributes']
        #for currentmain in range(len(listofmain)):
        currentverb = listofmain['verb'].rsplit(' : ', 1)
        currentsubject = listofmain['sys_fun_inter'].rsplit(' : ')
        currentattr = listofmain['flow_function_interface_item_system_state_stateset'].rsplit(' : ')
        currenSubState = listofmain['state_item_before_verb'].rsplit(' : ')
        currenSubStateValue = listofmain['statevalue_before_verb'].rsplit(' : ')
        currenLast = listofmain['statevalue_system_connection_stateset'].rsplit(' : ')
        #need to automatically catch this restrictions
        if (currenSubState[0] == 'State'):
            if (currenSubStateValue[0] != 'StateValue'):
                classlist.append("ERROR")
                return classlist
        if (currenLast[0].strip() == 'StateSet'):
            if(currentattr[0].strip() != 'State'):
                classlist.append("ERROR")
                return classlist
        if (currenLast[0].strip() == 'Connection'):
            if(currentattr[0].strip() != 'System'):
                classlist.append("ERROR")
                return classlist
        if (currenLast[0].strip() == 'StateValue'):
            if(currentattr[0].strip() != 'Item' and currentattr[0].strip() != 'State'):
                classlist.append("ERROR")
                return classlist
        if (currenLast[0].strip() == 'System'):
            if(currentattr[0].strip() != 'Interface'):
                classlist.append("ERROR")
                return classlist
        #
        for verbmain in verbsmain:
            flag = 0
            if (verbmain.upper() == currentverb[len(currentverb)-1].upper() ):
                for submain in subsmain:
                    flag = 0
                    if submain == currentsubject[0].strip():
                        flag = 1
                    if flag == 1 :
                        for attrmain in attrsmain:
                            if attrmain == currentattr[0].strip():
                                classlist.append('M'+str(i+1))
                                return(classlist)
        
                              

