#!/usr/bin/env python

import coral

def other_end(end):
    if end.association.connection[0]==end:
        return end.association.connection[1]
    return end.association.connection[0]

def copy_id_by_name(lang, model):
    assert str(lang.name) == str(model.name)
    if lang.__XMIid__() != model.__XMIid__():
        print "lang id",lang.__XMIid__()
        print "model id",model.__XMIid__()
        print model,"needs id from lang"
        model.__setXMIid__(lang.__XMIid__())
        
    classes_in_model={}
    print "Collecting classes"
    for cls in model.ownedElement.select(lambda c: c.oclIsKindOf(coral.lang.UML14.Class)):
        assert str(cls.name) != ""
        classes_in_model[str(cls.name)]=cls
    
    print "Checking ed to class id"
    for ed in lang.elements.select(lambda p: p.oclIsKindOf(coral.lang.SMD01.ElementDefinition)):
        if str(ed.name) in classes_in_model:
            print ed,"->",classes_in_model[str(ed.name)]
            cls=classes_in_model[str(ed.name)]
            if ed.__XMIid__() != cls.__XMIid__():
                print "Needs id from ed"
                cls.__setXMIid__(ed.__XMIid__())
            else:
                print "Good enough id already"
            
        else:
            print "no such thing", ed.name,"in",model

    print "Checking property ids"
    ends_in_model={}
    for end in model.__getAllParts__().select(lambda p: p.oclIsKindOf(coral.lang.UML14.AssociationEnd)):
        if not end.isNavigable:
            continue
        name=str(end.name)
        if name == "":
            name=str(end.participant.name).lower()
        name=str(other_end(end).participant.name)+"::"+name
        if ends_in_model.has_key(name):
            print "Panic!!! I don't know what to do with two properties with the same name"
            print name
        ends_in_model[name]=end
        #print "OK with ",name
        
    for attr in model.__getAllParts__().select(lambda p: p.oclIsKindOf(coral.lang.UML14.Attribute)):
        name=str(attr.__parent__().name)+"::"+str(attr.name)
        if name in ends_in_model:
            print "More Panic!!!!!!!!!"
        ends_in_model[name]=attr
        #print name
    
    for prop in lang.__getAllParts__().select(lambda p: p.oclIsKindOf(coral.lang.SMD01.Property)):
        prop_name=str(prop.__parent__().name)+"::"+str(prop.name)
        if not prop_name in ends_in_model:
            print "no such AssociationEnd or Attribute",prop.name
            print "skipping!"
            continue

        end_or_attr=ends_in_model[prop_name]
        if prop.__XMIid__() != end_or_attr.__XMIid__():
            print "Now do it to ",prop.name
            end_or_attr.__setXMIid__(prop.__XMIid__())
            print "Oh yeah!"
        else:
            pass
            #print "Good property id"
    
if __name__=="__main__":
    import sys
    if len(sys.argv)<3:
        print "Now write copyXMIidFromLangToUML language_file.xml UML_Model-describing-the-meta-model-from-which-the-language-file-should-be-created-in-the-future.xml"
        sys.exit(1)

    lang_prj=coral.loadDocument(sys.argv[1])
    model_prj=coral.loadDocument(sys.argv[2])

    for lang in lang_prj.contents():
        print "Found language ",lang.name
        print "Looking for model with the same name"
        for model in model_prj.contents().select(lambda m:m.oclIsKindOf(coral.lang.UML14.Model)):
            if str(model.name) == str(lang.name):
                print "OK I found mismatching id mass mitch xmi mitch mash id with the same name"
                print "Drums!", model.name,"==",lang.name
                copy_id_by_name(lang,model)
            else:
                print "NO! not",model.name

    model_prj.setFilename(str(model_prj.getFilename())+"fixed_xmiid")
    coral.saveDocument(model_prj)
