import os


from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods import Database, Structure

import os,sys
import test_util

odl_string = """
module Test {

  struct ZipCode {
    string zip;
    string plus4;
  };

  enum State {AL,CO,WI};

  struct Address {
    struct Streets {string street1; string street2; struct verydeep {string foo;} three;} street;
    enum TestEnum {One, Two} testEnum;
    State state;
    ZipCode zip;
  };

  class Person {
    struct sinside {string foo;};
    enum einside {One,Two};

    attribute Address address;
    attribute State state;

    attribute sinside s1;
    attribute einside e1;

    attribute struct priv1 {string one; struct sub {string two;} two;} nested;
    attribute enum priv2 {p1,p2} penum;
  };


};

"""
#"


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('Complex Structure Test %s driver' % tester.ods_driver_name)

    test_util.DbInit(DBNAME,odl_string)

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

    reload(Person)
    reload(Postman)
    reload(State)
    reload(Foo)
    
    db = Database.Database()
    db.open(DBNAME)

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

    tester.startTest('Testing Structure Creation')

    p = Person.new(db)
    pm = Postman.new(db)

    p.name = 'Mike Olson'
    pm.name = 'Mr. Postman'

    if db.lookup('Person'):
        db.unbind('Person')
    db.bind(p,'Person')

    tester.compare(1,hasattr(p.address,'street'))
    tester.compare(1,isinstance(p.address.street,Structure.Structure))
    tester.compare(1,hasattr(p.address.street,'street1'))
    tester.compare(1,hasattr(p.address.street,'street2'))

    tester.compare(1,hasattr(p.address,'city'))

    tester.compare(1,hasattr(p.address,'state'))
    tester.compare(str(State.State.elements[0]),str(p.address.state))


    tester.compare(1,hasattr(p.address,'zip'))
    tester.compare(1,isinstance(p.address.zip,Structure.Structure))
    tester.compare(1,hasattr(p.address.zip,'zip'))
    tester.compare(1,hasattr(p.address.zip,'plus4'))

    tester.compare(1,hasattr(p.address,'thePostman'))
    tester.compare(None,p.address.thePostman)


    tester.compare(1,hasattr(p.address,'poBoxes'))
    tester.compare(1,isinstance(p.address.poBoxes,LiteralCollection.LiteralListOfValues))

    p.address.street.street1 = "Street 1"
    p.address.street.street2 = "Street 2"
    p.address.city = "A City"
    p.address.state = State.State.elements[1]
    p.address.zip.zip = 'A Zip'
    p.address.zip.plus4 = 'Plus 4'
    
    p.address.thePostman = pm

    p.address.poBoxes.append("1234")

    tx.commit()
    tester.testDone()


    tester.startTest('Testing access and modify Structure')
    tx = db.new()
    tx.begin()

    p = db.lookup('Person')

    tester.compare("Street 1",p.address.street.street1)
    tester.compare("Street 2",p.address.street.street2)
    tester.compare("A City",p.address.city)
    tester.compare(str(State.State.elements[1]),str(p.address.state))
    tester.compare("A Zip",p.address.zip.zip)
    tester.compare("Plus 4",p.address.zip.plus4)

    tester.compare("Mr. Postman",p.address.thePostman.name)

    tester.compare(1,len(p.address.poBoxes))
    tester.compare(1,p.address.poBoxes.contains_element('1234'))

    #Change them all
    p.address.street.street1 = "Another Street 1"
    p.address.street.street2 = "Another Street 2"
    p.address.city = "Another City"
    p.address.state = State.State.elements[2]
    p.address.zip.zip = "Another Zip"
    p.address.zip.plus4 = "Another Plus 4"
    
    pm = Postman.new(db)
    pm.name = 'Mr. Postman the Second'
    p.address.thePostman = pm

    p.address.poBoxes.append("4321")


    tx.commit()
    tester.testDone()

    tester.startTest('Testing modified Structure')
    tx = db.new()
    tx.begin()

    p = db.lookup('Person')

    tester.compare("Another Street 1",p.address.street.street1)
    tester.compare("Another Street 2",p.address.street.street2)
    tester.compare("Another City",p.address.city)
    tester.compare(str(State.State.elements[2]),str(p.address.state))
    tester.compare("Another Zip",p.address.zip.zip)
    tester.compare("Another Plus 4",p.address.zip.plus4)

    tester.compare("Mr. Postman the Second",p.address.thePostman.name)

    tester.compare(2,len(p.address.poBoxes))
    tester.compare(1,p.address.poBoxes.contains_element('1234'))
    tester.compare(1,p.address.poBoxes.contains_element('4321'))

    tx.commit()
    tester.testDone()

    tester.startTest("Collection of Structures")
    tx = db.new()
    tx.begin()

    f = Foo.new(db)

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



    tx.commit()

    tester.testDone()

    db.close()
    tester.groupDone()

    return

if __name__ == '__main__':


    from Ft.Lib import TestSuite
    tester = TestSuite.TestSuite(1, 1)
    from Ft.Ods.StorageManager import Adapters
    tester.ods_driver_name = Adapters.g_driverName

    retVal = Test(tester)
    sys.exit(retVal)

