import os

#Test multiple threads leaving and joining a transaction

odl_string = '''
module Test {
class Foo
{
	attribute short threadNum;
};
};
'''
#'

NUM_THREADS = 10

from Ft.Ods import Database
try:
    import threading
    HAVE_THREADS=1
except ImportError:
    HAVE_THREADS = 0

import time

g_curThread = -1

g_tx = None

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

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

def Test(tester):
    if tester.test_data['driver'] == 'Dbm':
        tester.startTest("Not Supported")
        tester.warning("Test not supported for Dbm Driver")
        tester.testDone()
        return
    if not HAVE_THREADS:
        tester.startTest("Not Supported")
        tester.warning("Multithreaded not supported on this platform.")
        tester.testDone()
        return
    try:
        _Test(tester)
    finally:
        if os.path.exists('Test'):
            from distutils import dir_util
            dir_util.remove_tree('Test')

    
def _Test(tester):

    tester.startGroup("Leave and Join %s Driver" % tester.test_data['driver'])

    test_util.DbInit(DBNAME,odl_string)

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


    tester.testDone()

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

        tester.startTest("Run the threads")
        threads = []
        for ctr in range(NUM_THREADS):
            t = threading.Thread(None,test_thread,"Thread-%i"%ctr,(db,ctr,))
            t.start()
            threads.append(t)

        global g_tx
        g_tx = db.new()
        g_tx.begin()

        obj = Foo.new(db)
        obj.threadNum = -1
        db.bind(obj,"Foo")

        g_tx.leave()


        global g_curThread
        g_curThread = 0

        while g_curThread != NUM_THREADS:
            time.sleep(2)


        g_tx.join()
        g_tx.commit()

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



def test_thread(db,threadNum):
    global g_tx,g_curThread

    while g_curThread != threadNum:
        time.sleep(1)
    g_tx.join()

    f = db.lookup("Foo")
    f.threadNum = threadNum

    

    g_tx.leave()
    g_curThread = g_curThread + 1






