


from Ft.Ods import Database
from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods.MetaData import Module
from Ft.Ods.MetaData import Scope
from Ft.Ods.MetaData import PrimitiveKind
from Ft.Ods.MetaData import MetaKind
from Ft.Ods.MetaData import CollectionKind
from Ft.Ods.MetaData import Literal
from Ft.Ods.MetaData import Union
from Ft.Ods.MetaData import Constant
from Ft.Ods.MetaData import Structure
import test_metadata_util

def Test(tester,db,klass):


    tester.startGroup("Defining Scope Interface on %s Driver %s" % (klass.__name__,tester.test_data['driver']))

    
    tester.startTest("Bind")
    #We will use a module to test his because it is probaly the most stable ???
    tx=db.new()
    tx.begin()
    i = klass(db,None)
    m = Module.Module(db,None)
    m2 = Module.Module(db,None)
    i.bind("name1",m)
    m.bind("name2",m2)
    tx.commit()
    tester.testDone()

    rid1 = i._4ods_getId()
    rid2 = m._4ods_getId()
    rid3 = m2._4ods_getId()
    
    tester.startTest("resolve")
    tx=db.new()
    tx.begin()
    i = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid1)
    m = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid2)
    m2 = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid3)
    tester.testResults(m,i.resolve("name1"),done=0,msg="Single Resolve")
    tester.testResults(m2,m.resolve("name2"),done=0,msg="Single Resolve2")
    tester.testResults(m2,i.resolve("name1::name2"),done=0,msg="Multiple Resolve")
    try:
        i.resolve("foo")
    except Scope.Scope.NameNotFound:
        pass
    else:
        tester.error("No NameNot Found Exception")

    tester.testDone()


    tester.startTest("Unbind")
    i.unbind("name1")
    tx.commit()

    tx=db.new()
    tx.begin()
    i = db._4ods_getPersistentObjectById(Constants.Types.ROBJECT,rid1)
    try:
        i.resolve("name1")
    except Scope.Scope.NameNotFound:
        pass
    else:
        tester.error("No NameNotFoundException")
    tx.abort()
    tester.testDone()


    test_metadata_util.test_form_drop(tester,db,klass,'defines',Module.Module,nSided=1,accessListFunction='children')

    tx=db.new()
    tx.begin()
    test_metadata_util.test_create(tester,db,klass,'create_primitive_type',(PrimitiveKind.pk_short,),
                          {'meta_kind':MetaKind.mk_primitive_type,
                           'primitive_kind':PrimitiveKind.pk_short,
                           })
    max_size = Literal.Literal(db,None)
    subtype = db.schema().resolve('pk_short')
    test_metadata_util.test_create(tester,db,klass,'create_collection',
                          (CollectionKind.ck_list,max_size,subtype),
                          {'meta_kind':MetaKind.mk_collection,
                           'collection_kind':CollectionKind.ck_list,
                           'subtype':subtype,
                           'max_size':max_size,
                           })

    keytype = db.schema().resolve('pk_string')
    subtype = db.schema().resolve('pk_short')
    test_metadata_util.test_create(tester,db,klass,'create_dictionary_type',
                          (keytype,subtype),
                          {'meta_kind':MetaKind.mk_collection,
                           'collection_kind':CollectionKind.ck_dictionary,
                           'subtype':subtype,
                           'key_type':keytype,
                           })

    test_metadata_util.test_create(tester,db,klass,'create_operand',
                          ("1.5",),
                          {'meta_kind':MetaKind.mk_literal,
                           'literal_value':1.5,
                           })

    memberType = db.schema().resolve('pk_short')
    test_metadata_util.test_create(tester,db,klass,'create_member',
                          ("NewMember",memberType),
                          {'meta_kind':MetaKind.mk_member,
                           'name':"NewMember",
                           'type':memberType,
                           })


    caseType = db.schema().resolve('pk_short')
    case_label = Literal.Literal(db,None)
    test_metadata_util.test_create(tester,db,klass,'create_union_case',
                          ("NewCase",caseType,[case_label]),
                          {'meta_kind':MetaKind.mk_union_case,
                           'name':"NewCase",
                           'type':caseType,
                           },
                          {'case_labels':case_label,
                           })


    tx.abort()

    test_metadata_util.test_add_remove(tester,db,klass,'constant',
                              ("Foo","constType","constValue"),
                              argFactory={"constValue":Literal.Literal},
                              argResolve={"constType":"pk_short"},
                              testValues={"name":"Foo",
                                          "type":"constType",
                                          "the_Value":"constValue",
                                          "meta_kind":MetaKind.mk_constant,
                                          },
                              testIn="defines",
                              testResolve="Foo",
                              )

    test_metadata_util.test_add_remove(tester,db,klass,'type_definition',
                              ("TypeDef","alias"),
                              argFactory={},
                              argResolve={"alias":"pk_short"},
                              testValues={"name":"TypeDef",
                                          "alias":"alias",
                                          "meta_kind":MetaKind.mk_type_definition,
                                          },
                              testIn="defines",
                              testResolve="TypeDef",
                              )
    test_metadata_util.test_add_remove(tester,db,klass,'enumeration',
                              ("Enum",("One","Two")),
                              argFactory={},
                              argResolve={},
                              testValues={"name":"Enum",
                                          "meta_kind":MetaKind.mk_enumeration,
                                          },
                              testIn="defines",
                              testResolve="Enum",
                              )
    def CreateFields(db,value):
        from Ft.Ods.MetaData import Member
        memberType = db.schema().resolve('pk_short')
        field = Member.Member(db,value)
        field.name = "member"
        field.form_type(memberType)
        return field

    test_metadata_util.test_add_remove(tester,db,klass,'structure',
                              ("Struct","Fields"),
                              argFactory={},
                              argListFactory={"Fields":CreateFields},
                              argResolve={},
                              testValues={"name":"Struct",
                                          "meta_kind":MetaKind.mk_structure,
                                          },
                              testListValues={'fields':"Fields"},
                              testIn="defines",
                              testResolve="Struct",
                              )

    def CreateCases(db,values):
        from Ft.Ods.MetaData import Literal
        from Ft.Ods.MetaData import UnionCase
        case_label = Literal.Literal(db,None)
        caseType = db.schema().resolve('pk_short')
        case = UnionCase.UnionCase(db,None)
        case.name = 'case'
        case.form_type(caseType)
        case.add_case_labels(case_label)
        return case
    test_metadata_util.test_add_remove(tester,db,klass,'union',
                              ("Union","switchType","Cases"),
                              argFactory={},
                              argListFactory={"Cases":CreateCases},
                              argResolve={"switchType":'pk_short'},
                              testValues={"name":"Union",
                                          "meta_kind":MetaKind.mk_union,
                                          "switch_type":"switchType",
                                          },
                              testListValues={'cases':"Cases"},
                              testIn="defines",
                              testResolve="Union",
                              )

    test_metadata_util.test_add_remove(tester,db,klass,'exception',
                              ("Exception","result"),
                              argFactory={'result':Structure.Structure},
                              argListFactory={},
                              argResolve={},
                              testValues={"name":"Exception",
                                          "meta_kind":MetaKind.mk_exception,
                                          "result":"result",
                                          },
                              testListValues={},
                              testIn="defines",
                              testResolve="Exception",
                              )

    tester.groupDone()

