import os
from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods import Database
from Ft.Ods.Exception import IntegrityError, FtodsObjectNotFound
import os,sys
import test_util

odl_string = """
module Test {

  class Professor;

  interface Person {
    attribute string name;
    attribute string ssn;
    relationship list<Person> influenced_from inverse Person :: influences;
    relationship list<Person> influences inverse Person :: influenced_from;
  };

  class Student :Person (extent students) {
    attribute unsigned short student_id;
    relationship Professor learns_from inverse Test::Professor :: teaches;
    attribute Person roommate;
  };

  class Professor :Person{
    attribute unsigned short employee_id;
    relationship ::Test::Student teaches inverse Student :: learns_from;
  };
};

"""
#"


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('Interfaces')

    test_util.DbInit(DBNAME,odl_string)

    tester.startTest('Testing Generated syntax')
    try:
        from Test import Person
        from Test import Professor
        from Test import Student
        reload(Person)
        reload(Professor)
        reload(Student)
    except:
        tester.error('Error in syntax', 1)
    tester.testDone()

    
    db = Database.Database()
    db.open(DBNAME)

    try:
        tx = db.new()
        tx.begin()


        tester.startTest('Primitive Attributes')

        p = Professor.new(db)
        s = Student.new(db)

        p.ssn = '666-123-1234'
        p.name = 'Eblis Einstein'
        p.employee_id = 15

        s.ssn = '123-456-7890'
        s.name = 'Maro Faustus'
        s.student_id = 32

        tx.commit()

        pid = p._4ods_getOid()
        sid = s._4ods_getOid()

        tx = db.new()
        tx.begin()
        
        p = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,pid)
        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,sid)

        tester.compare('666-123-1234',p.ssn)
        tester.compare('Eblis Einstein',p.name)
        tester.compare(15,p.employee_id)

        tester.compare('123-456-7890',s.ssn)
        tester.compare('Maro Faustus',s.name)
        tester.compare(32,s.student_id)

        p.ssn = '9'
        p.name = 'Mike Olson'
        p.employee_id = 172

        s.ssn = '10'
        s.name = 'Uche Ogbuji'
        s.student_id = 3
        
        tx.commit()

        tx = db.new()
        tx.begin()
        
        p = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,pid)
        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,sid)

        tester.compare('9',p.ssn)
        tester.compare('Mike Olson',p.name)
        tester.compare(172,p.employee_id)

        tester.compare('10',s.ssn)
        tester.compare('Uche Ogbuji',s.name)
        tester.compare(3,s.student_id)

        tx.abort()
        tester.testDone()

        tester.startTest('Interface Attributes')

        tx = db.new()
        tx.begin()

        p = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,pid)
        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,sid)

        r = Student.new(db)

        s.roommate = r

        tx.commit()

        rid = r._4ods_getOid()

        tx = db.new()
        tx.begin()

        p = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,pid)
        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,sid)
        r = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,rid)

        tester.compare(r,s.roommate)

        tx.abort()

        tester.testDone()

        tester.startTest("Relationships")

        tx = db.new()
        tx.begin()

        p = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,pid)
        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,sid)
        r = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,rid)

        p.form_teaches(s)
        p.add_influences(s)
        r.add_influenced_from(p)

        tester.compare(s,p.teaches)
        tester.compare(2,len(p.influences))
        tester.compareIn(p.influences,s)
        tester.compareIn(p.influences,r)
        tester.compare(p,s.learns_from)
        tester.compare(1,len(s.influenced_from))
        tester.compare(p,s.influenced_from[0])
        tester.compare(1,len(r.influenced_from))
        tester.compare(p,r.influenced_from[0])
        
        tx.commit()
        
        tx = db.new()
        tx.begin()

        p = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,pid)
        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,sid)
        r = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,rid)

        tester.compare(s,p.teaches)
        tester.compare(2,len(p.influences))
        tester.compareIn(p.influences,s)
        tester.compareIn(p.influences,r)
        tester.compare(p,s.learns_from)
        tester.compare(1,len(s.influenced_from))
        tester.compare(p,s.influenced_from[0])
        tester.compare(1,len(r.influenced_from))
        tester.compare(p,r.influenced_from[0])

        p.drop_teaches(s)
        p.remove_influences(s)
        r.remove_influenced_from(p)
        
        tester.compare(None,p.teaches)
        tester.compare(0,len(p.influences))
        tester.compare(None,s.learns_from)
        tester.compare(0,len(s.influenced_from))
        tester.compare(0,len(r.influenced_from))

        tx.commit()

        tx = db.new()
        tx.begin()

        p = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,pid)
        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,sid)
        r = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,rid)

        tester.compare(None,p.teaches)
        tester.compare(0,len(p.influences))
        tester.compare(None,s.learns_from)
        tester.compare(0,len(s.influenced_from))
        tester.compare(0,len(r.influenced_from))

        tester.testException(p.form_teaches,(p,),IntegrityError)

        tx.abort()

        tester.testDone()

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




