import sys, os

from Ft.Ods import Constants, Object, Enumeration, Structure, Union, Collections, Exception
from Ft.Ods.Collections import DictionaryBase
from Ft.Ods.StorageManager.Adapters import Util

from Ft.Ods import StorageManager

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

class DummyFactory:
    def _4ods_endTransaction(self,*args):
        pass


def TestConstants(tester):

    tester.startGroup("StorageManager Constants")

    tester.startTest("StringTypeCheck")
    tester.testException(Constants.StringTypeCheck,(1,-1),TypeError)
    tester.testDone()

    tester.startTest("IntTypeCheck")
    tester.testException(Constants.IntTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("BooleanTypeCheck")
    tester.testException(Constants.BooleanTypeCheck,('f',-1),TypeError)
    tester.testException(Constants.BooleanTypeCheck,(7,-1),TypeError)
    tester.testDone()

    tester.startTest("LongTypeCheck")
    tester.testException(Constants.LongTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("DoubleTypeCheck")
    tester.testException(Constants.DoubleTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("CharTypeCheck")
    tester.testException(Constants.CharTypeCheck,(1,-1),TypeError)
    tester.testException(Constants.CharTypeCheck,('foo',-1),TypeError)
    tester.testDone()

    tester.startTest("OctetTypeCheck")
    tester.testException(Constants.OctetTypeCheck,('f',-1),TypeError)
    tester.testException(Constants.OctetTypeCheck,(10000,-1),TypeError)
    tester.testDone()

    tester.startTest("DateTypeCheck")
    tester.testException(Constants.DateTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("TimeTypeCheck")
    tester.testException(Constants.TimeTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("IntervalTypeCheck")
    tester.testException(Constants.IntervalTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("TimeStampTypeCheck")
    tester.testException(Constants.TimestampTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("VoidTypeCheck")
    tester.testException(Constants.VoidTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("PObjectTypeCheck")
    tester.testException(Constants.PObjectTypeCheck,('f',-1),TypeError)
    o = Object.Object(None,None)
    o._typeIds = (1,)
    tester.testException(Constants.PObjectTypeCheck,(o,-1),TypeError)
    tester.testDone()

    tester.startTest("RObjectTypeCheck")
    tester.testException(Constants.RObjectTypeCheck,('f',-1),TypeError)
    tester.testDone()

    tester.startTest("EnumerationTypeCheck")
    tester.testException(Constants.EnumerationTypeCheck,('f',-1),TypeError)
    e = Enumeration.EnumElement(None,'',1,'',1)
    tester.testException(Constants.EnumerationTypeCheck,(e,-1),TypeError)
    tester.testDone()

    tester.startTest("StructureTypeCheck")
    tester.testException(Constants.StructureTypeCheck,('f',-1),TypeError)
    s = Structure.Structure(None,None)
    s._typeIds = (1,)
    tester.testException(Constants.StructureTypeCheck,(s,-1),TypeError)
    tester.testDone()

    tester.startTest("UnionTypeCheck")
    tester.testException(Constants.UnionTypeCheck,('f',-1),TypeError)
    u = Union.Union(None,None)
    u._typeIds = (1,)
    tester.testException(Constants.UnionTypeCheck,(u,-1),TypeError)
    tester.testDone()

    tester.startTest("ListTypeCheck")
    tester.testException(Constants.ListTypeCheck,('f',-1),TypeError)
    c = Collections.LiteralSetOfValues(None,None,1,1,None)
    c._typeIds = (1,)
    tester.testException(Constants.ListTypeCheck,(c,-1),TypeError)
    tester.testDone()

    tester.startTest("SetTypeCheck")
    tester.testException(Constants.SetTypeCheck,('f',-1),TypeError)
    c = Collections.LiteralListOfValues(None,None,1,1,None)
    c._typeIds = (1,)
    tester.testException(Constants.SetTypeCheck,(c,-1),TypeError)
    tester.testDone()

    tester.startTest("BagTypeCheck")
    tester.testException(Constants.BagTypeCheck,('f',-1),TypeError)
    c = Collections.LiteralSetOfValues(None,None,1,1,None)
    c._typeIds = (1,)
    tester.testException(Constants.BagTypeCheck,(c,-1),TypeError)
    tester.testDone()

    tester.startTest("DictionaryTypeCheck")
    tester.testException(Constants.DictionaryTypeCheck,('f',-1),TypeError)
    d = DictionaryBase.DictionaryBase(None,None,1,1,1,1,None)
    d._typeIds = (1,)
    tester.testException(Constants.DictionaryTypeCheck,(c,-1),TypeError)
    tester.testDone()

    tester.startTest("ArrayTypeCheck")
    tester.testException(Constants.ArrayTypeCheck,('f',-1),Exception.FtodsUnsupportedError)
    tester.testDone()

    tester.groupDone()


def TestConnectionString(tester):
    tester.startTest("Connection String Exceptions")
    tester.testException(Util.SplitDbConnectString,('ods:molson/one/two@fourthought.com:foo',),Exception.FtodsInvalidConnectionString)
    tester.testException(Util.SplitDbConnectString,('ods:molson@fourthought.com@foo',),Exception.FtodsInvalidConnectionString)
    tester.testException(Util.SplitDbConnectString,('ods:molson@fourthought.com:foo:bar:baz',),Exception.FtodsInvalidConnectionString)
    tester.testDone()

def TestTransaction(tester):

    tester.startGroup("Transaction")

    tester.startTest("Transaction In Progress")
    sm = StorageManager.StorageManager(DummyFactory(),DBNAME)
    sm.begin()
    try:
        tester.testException(sm.begin,(),Exception.TransactionInProgress)
    finally:
        sm.abort()
    tester.testDone()

    tester.startTest("Transaction not In Progress")
    sm = StorageManager.StorageManager(DummyFactory(),DBNAME)
    tester.testException(sm.abort,(),Exception.TransactionNotInProgress)
    tester.testException(sm.commit,(),Exception.TransactionNotInProgress)
    tester.testException(sm.checkpoint,(),Exception.TransactionNotInProgress)
    tester.testException(sm.join,(),Exception.TransactionNotInProgress)
    tester.testException(sm.leave,(),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_flush,(),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_registerNewLiteralClass,(None,None,None),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_registerNewPersistentObject,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_registerNewBlob,(None,None,None),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_registerModifiedPersistentObject,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_registerModifiedBlob,(None,None),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_unregisterPersistentObject,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_deletePersistentObject,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_deleteBlob,(None,None,None),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_createLiteralInstance,(None,None,None),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_lookup,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_bind,(None,None),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_unbind,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_getAllBindings,(),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_getObjectBindings,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._4ods_isBound,(None,),Exception.TransactionNotInProgress)
    tester.testException(sm._StorageManager__getObject,(None,None,None),Exception.TransactionNotInProgress)
    tester.testDone()

    tester.startTest("Object Not Found")
    sm = StorageManager.StorageManager(DummyFactory(),DBNAME)
    sm.begin()
    try:
        tester.testException(sm._4ods_createLiteralInstance,(-1,-1,None),Exception.FtodsObjectNotFound)
        tester.testException(sm._4ods_readBlob,(-1,),Exception.FtodsObjectNotFound)
        tester.testException(sm._StorageManager__getObject,([],-1,None),Exception.FtodsObjectNotFound)
    finally:
        sm.abort()
    tester.testDone()

    tester.startTest("Binding Exceptions")
    sm = StorageManager.StorageManager(DummyFactory(),DBNAME)
    sm.begin()
    try:
        sm._bindings['foo'] = 1
        tester.testException(sm._4ods_bind,(None,'foo'),Exception.ObjectNameNotUnique)
    finally:
        sm.abort()
    tester.testDone()

    tester.startTest("Misc. Exceptions")
    sm = StorageManager.StorageManager(DummyFactory(),DBNAME)
    tester.testException(sm._4ods_runQuery,(None,),Exception.FtodsUnsupportedError)
    tester.testDone()

    tester.groupDone()
    

def TestDatabaseExceptions(tester):
    tester.startGroup("Database Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()


def TestMetaDataExceptions(tester):
    tester.startGroup("MetaData Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def TestCollectionExceptions(tester):
    tester.startGroup("Collection Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()


def TestOifExceptions(tester):
    tester.startGroup("OIF Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def TestOqlExceptions(tester):
    tester.startGroup("OQL Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def TestOdlExceptions(tester):
    tester.startGroup("ODL Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def TestGeneratedExceptions(tester):
    tester.startGroup("pstub exceptions Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def TestStructureExceptions(tester):
    tester.startGroup("Structure Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def TestEnumerationExceptions(tester):
    tester.startGroup("Enumeration Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def TestUnionExceptions(tester):
    tester.startGroup("Union Exceptions")
    tester.startTest("Not Done")
    tester.warning("Not TEsted")
    tester.testDone()
    tester.groupDone()

def Test(tester):

    tester.startGroup("Test Exceptions")

    TestConstants(tester)
    TestConnectionString(tester)
    TestTransaction(tester)
    TestDatabaseExceptions(tester)
    TestMetaDataExceptions(tester)
    TestCollectionExceptions(tester)

    TestOdlExceptions(tester)
    TestOifExceptions(tester)
    TestOqlExceptions(tester)

    TestGeneratedExceptions(tester)

    TestStructureExceptions(tester)
    TestEnumerationExceptions(tester)
    TestUnionExceptions(tester)

    tester.groupDone()



