import os, sys
from Ft.Ods.StorageManager.Adapters import Constants


odl_string = '''
module Test {

class Professor;

class Student (extent students)
{
	attribute string name;
	attribute unsigned short student_id;
        attribute short age;
        attribute double weight;
	readonly attribute string ssn;
	relationship Professor learns_from inverse Test::Professor :: teaches;
};

class Professor
{
	attribute string name;
	attribute unsigned short employee_id;
	attribute string ssn;
	relationship list<::Test::Student> teaches inverse Student :: learns_from;
};
};

'''
#'

from Ft import Ods

from Ft.Ods import Database
import test_util
DBNAME=os.environ.get("ODS_TEST_DB","ods:test")

pKlass = """class ProfessorImp(Professor.Professor_stub):

    def __del__(self):
        pass
"""

sKlass = """class StudentImp(Student.Student_stub):
    def __del__(self):
        pass
"""

def test_init():
    test_util.DbInit(DBNAME,odl_string)
    return


def test1(p,s):

    p = p(None,None)
    s = s(None,None)

    return

def test2(p,s):

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

    try:
        tx = db.new()
        tx.begin()
        p = p(db,None)
        s = s(db,None)

        tx.commit()
    finally:
        db.close()

def test3(p,s):
    db = Database.Database()
    db.open(DBNAME)
    try:
        tx = db.new()
        tx.begin()
        s = s(db,None)

        ext = db.lookup('ext')
    
        tx.commit()
    finally:
        db.close()
    return

def test4(p,s):
    
    db = Database.Database()
    db.open(DBNAME)
    try:
        tx = db.new()
        tx.begin()
        s = s(db,None)

        db.bind(s,"Foo")

        tx.commit()
    finally:
        db.close()

    del s

    return

def test5(p,s):
    
    db = Database.Database()
    db.open(DBNAME)

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

        p = p(db,None)
        s = s(db,None)
        s.form_learns_from(p)
        
        db.bind(p,"Prof")
        
        tx.commit()
    finally:
        db.close()
    Ods.FreePersistentObject(p)

    return


def test6(p,s):

    db = Database.Database()
    db.open(DBNAME)
    try:
        tx = db.new()
        tx.begin()

        import circular_reference_test
        circular_reference_test.ProfessorImp = p

        p = db.lookup("Prof")

        tx.commit()
    finally:
        db.close()

    Ods.FreePersistentObject(p)

    return


def test7():

    db = Database.Database()
    db.open(DBNAME)
    try:
        tx = db.new()
        tx.begin()

        p = db.lookup("Prof")

        tx.commit()
    finally:
        db.close()

    Ods.FreePersistentObject(p)

    return


def test8():

    db = Database.Database()
    db.open(DBNAME)
    try:
        tx = db.new()
        tx.begin()

        p = db.lookup("Prof")

        tx.commit()
    finally:
        db.close()

    Ods.FreePersistentObject(p)

    return


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("Circular Reference %s Driver" % tester.test_data['driver'])


    from Ft.Lib import Cyclops
    z = Cyclops.CycleFinder()


    tester.startTest("Test Init")
    z.run(test_init,())
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    from Test import Professor
    from Test import Student
    reload(Professor)
    reload(Student)

    exec pKlass
    exec sKlass


    tester.startTest("Test 1")
    z.run(test1,(ProfessorImp,StudentImp))
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    tester.startTest("Test 2")
    z.run(test2,(ProfessorImp,StudentImp))
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    tester.startTest("Test 3")
    z.run(test3,(ProfessorImp,StudentImp))
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    tester.startTest("Test 4")
    z.run(test4,(ProfessorImp,StudentImp))
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    tester.startTest("Test 5")
    z.run(test5,(ProfessorImp,StudentImp))
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    tester.startTest("Test 6")
    z.run(test6,(ProfessorImp,StudentImp))
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    tester.startTest("Test 7")
    z.run(test7,())
    z.find_cycles(1)
    if len(z.cycles) != 0:
        z.show_cycles()
        tester.testError("Should not be cycles")
    z.clear()
    tester.testDone()

    tester.groupDone()

