import os


from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods import Database, Union, TimeFactory
import os,sys
import test_util

odl_string = """
module Test {

  enum UnionCase {PRIME,OBJECT,STRUCT,LITERAL,COLLECTION,ENUM};

  class MyClass {
    attribute string name;
  };

  struct MyStruct {
    string name;
  };

  typedef list<string> StringList;

  enum Color {Red,Green,Blue};

  union MyUnion switch (UnionCase) {
    case PRIME:
       string str;
    case OBJECT:
      MyClass cl;
    case STRUCT:
      MyStruct st;
    case LITERAL:
      time t;
    case COLLECTION:
      StringList sl;
    case ENUM:
      Color c;
  };

  class Foo {
    attribute MyUnion u;
  };
};

"""
#"


DBNAME=os.environ.get("ODS_TEST_DB","ods:test")

def Test(tester):
    try:
        _Test(tester)
    finally:
        if os.path.exists('Test'):
            from distutils import dir_util
            dir_util.remove_tree('Test')
        pass
    

def _Test(tester):

    tester.startGroup('Union Test %s driver' % tester.test_data['driver'])

    test_util.DbInit(DBNAME,odl_string)

    tester.startTest('Testing Generated syntax')
    try:
        from Test import Foo
        from Test import MyClass
        import Test
    except:
        tester.error('Error in syntax', 1)
    tester.testDone()

    reload(Foo)
    reload(MyClass)
    reload(Test)
    
    db = Database.Database()
    db.open(DBNAME)
    try:
        tx = db.new()
        tx.begin()

        tester.startTest('Testing Setting Union to a primitive')

        f = Foo.new(db)

        if db.lookup('Foo'):
            db.unbind('Foo')
        db.bind(f,'Foo')

        f.u = Test.MyUnion(Test.UnionCase.PRIME,'A String')
        tx.commit()
        tester.testDone()

        tester.startTest('Test primitive persistence and object setting')
        tx = db.new()
        tx.begin()

        f = db.lookup('Foo')
        tester.compare(Test.UnionCase.PRIME,f.u._d)
        tester.compare("A String",f.u._v)
        tester.compare("A String",f.u.str)

        c = MyClass.new(db)

        f.u = Test.MyUnion(Test.UnionCase.OBJECT,c)

        if db.lookup('klass'):
            db.unbind('klass')
        db.bind(c,'klass')
        tx.commit()
        tester.testDone()


        tester.startTest('Test object persistence and structure setting')
        tx = db.new()
        tx.begin()

        f = db.lookup('Foo')
        c = db.lookup('klass')

        tester.compare(Test.UnionCase.OBJECT,f.u._d)
        tester.compare(c,f.u._v)
        tester.compare(c,f.u.cl)

        st = Test.MyStruct(db)
        st.name = "Foo"
        f.u = Test.MyUnion(Test.UnionCase.STRUCT,st)

        tx.commit()
        tester.testDone()

        tester.startTest('Test struct persistence and literal setting')
        tx = db.new()
        tx.begin()

        f = db.lookup('Foo')

        tester.compare(Test.UnionCase.STRUCT,f.u._d)
        tester.compare("Foo",f.u._v.name)
        tester.compare("Foo",f.u.st.name)

        t = TimeFactory.from_hmsm(10,10,10,10)

        f.u = Test.MyUnion(Test.UnionCase.LITERAL,t)

        tx.commit()
        tester.testDone()

        tester.startTest('Test literal persistence and collection setting')
        tx = db.new()
        tx.begin()

        f = db.lookup('Foo')

        tester.compare(Test.UnionCase.LITERAL,f.u._d)
        tester.compare(10,f.u._v.minute())
        tester.compare(10,f.u.t.minute())

        sl = Test.StringList(db)
        sl.insert_element("Foo")

        f.u = Test.MyUnion(Test.UnionCase.COLLECTION,sl)

        tx.commit()
        tester.testDone()


        tester.startTest('Test collection persistence and enum setting')
        tx = db.new()
        tx.begin()

        f = db.lookup('Foo')

        tester.compare(Test.UnionCase.COLLECTION,f.u._d)
        tester.compare(1,f.u._v.contains_element('Foo'))
        tester.compare(1,f.u.sl.contains_element('Foo'))

        f.u = Test.MyUnion(Test.UnionCase.ENUM,Test.Color.Green)

        tx.commit()
        tester.testDone()

        tester.startTest('Test enum persistence')
        tx = db.new()
        tx.begin()

        f = db.lookup('Foo')

        tester.compare(Test.UnionCase.ENUM,f.u._d)
        tester.compare(Test.Color.Green,f.u._v)
        tester.compare(Test.Color.Green,f.u.c)

        tx.commit()
        tester.testDone()

    finally:
        db.close()
    tester.groupDone()

    return

