from rdflib import Graph, BNode
from rdflib.namespace import RDFS
from rdflib import ConjunctiveGraph, URIRef, RDFS, RDF, Namespace, OWL

def get_instances(keyword):
    an_list=[]
    with open('instances.txt') as f:
        for data in f:
            if (data.strip()).endswith(keyword):
                spliter_1 = data.split('$')
                spliter_2 = spliter_1[0].split("#")
                an_list.append(spliter_2[len(spliter_2) - 1])
    return an_list


'''Find Boilerplate subject of each main - return list'''
def get_subjects(bnodes_uriref):
    setOfElems = set()
    duplicate_uri = []
    bnodes = []
    rdf_syntax = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'

    for elem in range (len(bnodes_uriref)):
        if not bnodes_uriref[elem] in setOfElems:
            setOfElems.add(bnodes_uriref[elem])  
        else:
            duplicate_uri.append(bnodes_uriref[elem])
        if   rdf_syntax == str(bnodes_uriref[elem]) :
            bnodes = bnodes_uriref[:elem] 

    try:
        duplicate_uri.remove(URIRef(rdf_syntax)) 
    except:
        pass
    
    subject_list = []
    for i in duplicate_uri:
        if i in bnodes:
            spliter = str(i).split("#")
            subject_list.append(str(spliter[1]))
    return(subject_list)


'''Find Boilerplate classes between subject and verb - return list'''
def get_related_to_subject(bnodes_uriref):
    related_to_subject_list = []
    bnodes_uriref = [str(i) for i in bnodes_uriref]
    for rel_to_sub in bnodes_uriref:
        if "isRelatedToSubject" in rel_to_sub:
            tmp = rel_to_sub.split("isRelatedToSubject")
            if tmp[1] != '':
                related_to_subject_list.append(tmp[1])
    return(related_to_subject_list)


'''Find Boilerplate Verb - return list'''
def get_verb(bnodes_uriref):
    verb_list = []
    bnodes_uriref = [str(i) for i in bnodes_uriref]
    for rel_to_sub in bnodes_uriref:
        if "LO" in rel_to_sub:
            tmp = rel_to_sub.split("#")
            if tmp[1] != '':
                verb_list.append(tmp[1])
    return(verb_list)


'''Check if Boilerplate has quantifier - return list'''
def check_quantifier(bnodes_uriref):
    bnodes_uriref = [str(i) for i in bnodes_uriref]
    quantity = [(rel_to_sub) for rel_to_sub in bnodes_uriref if "isRelatedToQuantity" in rel_to_sub]
    uom = [(rel_to_sub) for rel_to_sub in bnodes_uriref if "isRelatedtoUOM" in rel_to_sub]
    if quantity and uom:
        return True


'''Find Boilerplate Attribute - return list'''
def get_attribute(bnodes_uriref, subjects, related_subjects, verbs):
    bnodes = []
    attribute_list = []
    bnodes_uriref = [str(i) for i in bnodes_uriref]
    for attribute in bnodes_uriref:
        if "isRelatedToSubject" in attribute:
            pass
        elif "isRelatedTo" in attribute:
            tmp = attribute.split("#")
            if tmp[1] != '':
                tmp = tmp[1].split("isRelatedTo")
                attribute_list.append(tmp[1])
        #to be deleted in only exist isRelatedTo
        elif "isRelatedto" in attribute:
            tmp = attribute.split("#")
            if tmp[1] != '':
                tmp = tmp[1].split("isRelatedto")
                attribute_list.append(tmp[1])
    attribute_list = list(filter(("Action").__ne__, attribute_list))
    attribute_list = list(filter(("Attribute").__ne__, attribute_list))
    attribute_list = list(filter(("Quantity").__ne__, attribute_list))
    attribute_list = list(filter(("UOM").__ne__, attribute_list))
    #discuss with kostas if this needed
    attribute_list = list(filter(("TraversingConcept").__ne__, attribute_list))
    
    tmp_list = []
    for i in bnodes_uriref:
        if not "isRelatedTo" in i:
            if not "isRelatedto" in i:
                tmp = i.split("#")
                if tmp[1] != '':
                    tmp_list.append(tmp[1])
    
    tmp_list = list(filter(("nil").__ne__, tmp_list))
    tmp_list = list(filter(("Restriction").__ne__, tmp_list))
    tmp_list = list(filter(("Class").__ne__, tmp_list))
    tmp_list = list(filter(("Action").__ne__, tmp_list))
    tmp_list = list(filter(("Quantity").__ne__, tmp_list))
    tmp_list = list(filter(("UnitOfMeasurement").__ne__, tmp_list))
    for i in subjects:
        tmp_list = list(filter((i).__ne__, tmp_list))
    for i in related_subjects:
        tmp_list = list(filter((i).__ne__, tmp_list))
    for i in verbs:
        tmp_list = list(filter((i).__ne__, tmp_list))

    res = attribute_list + tmp_list
    res = list(dict.fromkeys(res))
    return(res)



'''Find Main syntax - return a dict with the syntax'''
def get_main_sytax():
    get_main = get_instances("RBO#Main")
    main_dict = {}
    for main in get_main:
        bnodes = []
        p = URIRef("http://delab.csd.auth.gr/ontologies/2018/RBO#" + main)
        for s, p, o in g.triples((p, None, None)):
            if isinstance(o, BNode):
                bnodes.append(o)
        bnodes.sort()

        for bn in bnodes:
            for objects in g.objects(subject=BNode(bn)):
                if isinstance(objects, BNode):
                    bnodes.append(objects)
                
        bnodes.sort()

        bnodes_uriref = []

        for bn in bnodes:
            for objects in g.objects(subject=BNode(bn)):
                if isinstance(objects, URIRef):
                    bnodes_uriref.append(objects)
        
        main_dict[main] = {}
        main_dict[main]["Subject"] = get_subjects(bnodes_uriref)
        main_dict[main]["Related_to_Subject"] = get_related_to_subject(bnodes_uriref)
        main_dict[main]["Verbs"] = get_verb(bnodes_uriref)
        main_dict[main]["Quantifier"] = check_quantifier(bnodes_uriref)
        main_dict[main]["Attributes"] = get_attribute(bnodes_uriref, main_dict[main]["Subject"], main_dict[main]["Related_to_Subject"], main_dict[main]["Verbs"])


    return main_dict


'''Find Prefix syntax - return a dict with the syntax'''
def get_prefix_syntax():
    prefix_dict={}
    prefix_list = []
    get_prefix = get_instances("RBO#Prefix")
    for prefix in get_prefix:
        prefix_list.extend(get_instances(prefix))
    for prefix in prefix_list:
        prefix_dict[prefix] = {}
        prefix_dict[prefix]["Verbs"] = []
        bnodes_uriref = find_triples(prefix)
        subclass_data = []
        for per in bnodes_uriref:
            tmp = get_instances(str(per))
            for i in tmp:
                subclass_data.append(i)
        for pre in subclass_data:
            tmp_list = []
            tmp_list2 = find_triples(pre)
            tmp_list2 = [str(i) for i in tmp_list2]
            for i in tmp_list2:
                tmp = i.split("#")
                tmp_list.append(tmp[1])
            tmp_list = list(filter(("nil").__ne__, tmp_list))
            tmp_list = list(filter(("Restriction").__ne__, tmp_list))
            tmp_list = list(filter(("Class").__ne__, tmp_list))
            tmp_list = list(filter(("Action").__ne__, tmp_list))
            tmp_list = list(filter(("Quantity").__ne__, tmp_list))
            tmp_list = list(filter(("UnitOfMeasurement").__ne__, tmp_list))
            isrelated = []
            sub = []
            for i in tmp_list:
                if "isRelatedTo" in i:
                    isrelated.append(i)
                else:
                    sub.append(i)
            for i in sub:
                for j in isrelated:
                    if i in j:
                        prefix_dict[prefix]["Attribute"] = i
                        sub.remove(i)
            if tmp_list2:
                ver = get_verb(tmp_list2)
                prefix_dict[prefix]["Verbs"].append(ver)
                for i in ver:
                    sub.remove(i)
            prefix_dict[prefix]["Suject"] = sub
    return prefix_dict        
            
    

            


'''Find the triples of the prefix - return list.type(URIRef)'''
def find_triples(prefix):
    bnodes = []
    URIRef_list = []
    per = URIRef("http://delab.csd.auth.gr/ontologies/2018/RBO#" + prefix)
    for s, p, o in g.triples((per, None, None)):
        if isinstance(o, BNode):
            bnodes.append(o)
    bnodes.sort()

    for bn in bnodes:
        for objects in g.objects(subject=BNode(bn)):
            if isinstance(objects, BNode):
                bnodes.append(objects)     
    bnodes.sort()
    bnodes_uriref = []

    for bn in bnodes:
        for objects in g.objects(subject=BNode(bn)):
            if isinstance(objects, URIRef):
                bnodes_uriref.append(objects)
    return bnodes_uriref
        

file2 = open(r"instances.txt","w+") 
file3 = open(r"disjoint.txt","w+") 

g = Graph()
g.load("../Ontologies/Mokos_18_1_7_47.ttl", format="turtle")

for subj, obj in g.subject_objects(predicate=RDFS.subClassOf):
    subClass = subj + "$"+ obj + "\n"
    file2.write(subClass)

for subj, obj in g.subject_objects(predicate=OWL.disjointWith):
    subClass = subj + "$"+ obj + "\n"
    file3.write(subClass)

get_prefix_syntax()


    



    
    
    








