
from Ft.Server.Server import FtServerServerException, Error
from Ft.Server.Common import AclConstants, ResourceTypes

from Ft.Server import FTSERVER_NAMESPACE
from Ft.Xml.XLink import XLINK_NAMESPACE

from Ft.Xml.Lib import TreeCompare

import test_helper

def test_create(tester):


    tester.startTest("Create Container")

    #Create container
    repo = test_helper.GetRepo(tester)
    test = repo.createContainer("/test",0)
    tester.compare('/test',test.getDisplayPath())
    tester.compare(ResourceTypes.ResourceType.CONTAINER,repo.hasResource('/test'))
    tester.compare(ResourceTypes.ResourceType.CONTAINER,test.getResourceType())
    tester.compare(1,test.isResourceType(ResourceTypes.ResourceType.CONTAINER))
    tester.compare(1,test.isResourceType(ResourceTypes.ResourceType.XML_DOCUMENT))
    tester.compare(1,test.isResourceType(ResourceTypes.ResourceType.RAW_FILE))

    testMd = test.getMetaDataResource().getContent()
    testContent = test.getContent()

    cd,md = test_helper.TestMetaData(tester,
                                     testMd,
                                     'test',
                                     ResourceTypes.ResourceType.CONTAINER,
                                     [],
                                     tester.test_data['userName'],
                                     'text/xml',
                                     str(len(testContent)),
                                     []
                                     )


    tester.compare(EMPTY_CONTAINER_CONTENT,testContent,func=TreeCompare.TreeCompare)

    test_helper.TestContainerRdf(tester,
                                 repo,
                                 test.getPath().absolutePath,
                                 len(testContent),
                                 tester.test_data['userName'],
                                 cd,
                                 md,
                                 [])


    #Make sure that the parent was modified
    pMd = test.getParent().getMetaDataResource().getContent()
    pContent = test.getParent().getContent()


    aclKeys = [AclConstants.DELETE_ACCESS,
               AclConstants.READ_ACCESS,
               AclConstants.WRITE_ACCESS,
               AclConstants.EXECUTE_ACCESS,
               AclConstants.CHANGE_PERMISSIONS_ACCESS,
               AclConstants.CHANGE_OWNER_ACCESS,
               AclConstants.WRITE_USER_MODEL_ACCESS]
    owner = AclConstants.SUPER_USER_GROUP_NAME
    content = REPO_CONTAINER_CONTENT
    children = ['ftss',
                'test']

    cd,md = test_helper.TestMetaData(tester,
                                     pMd,
                                     '/',
                                     ResourceTypes.ResourceType.CONTAINER,
                                     aclKeys,
                                     owner,
                                     'text/xml',
                                     str(len(pContent)),
                                     []
                                     )


    tester.compare(content,pContent,func=TreeCompare.TreeCompare)

    test_helper.TestContainerRdf(tester,
                                 repo,
                                 repo.getPath().absolutePath,
                                 len(pContent),
                                 owner,
                                 cd,
                                 md,
                                 children
                                 )

    repo.txCommit()




    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource("/test")
    tester.compare('/test',test.getPath().displayPath)
    tester.compare('/test',test.getPath().absolutePath)
    tester.compare(ResourceTypes.ResourceType.CONTAINER,test.hasResource('/test'))
    repo.txRollback()
    tester.testDone()


    #Create container with deap parents
    repo = test_helper.GetRepo(tester)
    repo.createContainer("/test/foo/bar",1)
    tester.compare(ResourceTypes.ResourceType.CONTAINER,repo.hasResource('/test/foo'))
    tester.compare(ResourceTypes.ResourceType.CONTAINER,repo.hasResource('/test/foo/bar'))
    repo.txCommit()

    repo = test_helper.GetRepo(tester)
    tester.compare(ResourceTypes.ResourceType.CONTAINER,repo.hasResource('/test/foo'))
    tester.compare(ResourceTypes.ResourceType.CONTAINER,repo.hasResource('/test/foo/bar'))
    repo.txRollback()
                   
    tester.testDone()

    return



def test_access(tester):


    tester.startTest("Fetch Container MetaData")

    repo = test_helper.GetRepo(tester)

    test = repo.fetchResource('/test')

    testMd = test.getMetaDataResource().getContent()
    testContent = test.getContent()

    cd,md = test_helper.TestMetaData(tester,
                                     testMd,
                                     'test',
                                     ResourceTypes.ResourceType.CONTAINER,
                                     [],
                                     tester.test_data['userName'],
                                     'text/xml',
                                     str(len(testContent)),
                                     []
                                     )


    tester.compare(PARENT_CONTAINER_CONTENT%('foo'), testContent, diff=1,
                   func=TreeCompare.TreeCompare)


    test_helper.TestContainerRdf(tester,
                                 repo,
                                 test.getPath().absolutePath,
                                 len(testContent),
                                 tester.test_data['userName'],
                                 cd,
                                 md,
                                 ['foo'])

    repo.txRollback()

    tester.testDone()

    
    tester.startTest("Container User List Access")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    foo = test.fetchResource('foo')
    tester.compare(1,len(test))
    tester.compare(foo.getPath(),test[0].getPath())
    rt = test[:]
    tester.compare(1,len(rt))
    tester.compare(foo.getPath(),rt[0].getPath())
    tester.compare(0,test.index(rt[0]))
    tester.testDone()


    tester.startTest("Container User Dict Access")
    keys = test.keys()
    tester.compare(1,len(keys))
    tester.compareIn(keys,'foo')

    items = test.items()
    tester.compare(1,len(items))
    tester.compareIn(items,('foo',foo))

    values = test.values()
    tester.compare(1,len(values))
    tester.compare(foo.getPath(),values[0].getPath())

    tester.compare(1,test.has_key('foo'))
    tester.compare(0,test.has_key('foobar'))

    tester.compare(foo.getPath(),test.get('foo').getPath())
    tester.compare(None,test.get('foobar'))
    repo.txRollback()

    tester.testDone()



def test_delete(tester):


    tester.startTest("Test Delete Empty")

    repo = test_helper.GetRepo(tester)
    repo.createContainer('/test/child')
    repo.txCommit()

    repo = test_helper.GetRepo(tester)
    repo.deleteResource('/test/child')
    stmts = repo.getModel().complete('/test/child',None,None)
    tester.compare(0,len(stmts))
    tester.compare(0,repo.hasResource('/test/child'))
    tester.compare(0,repo.hasResource('ftss:/test/child'))
    repo.txCommit()
    tester.testDone()


    tester.startTest("Parent Modification after delete")
    repo = test_helper.GetRepo(tester)

    test = repo.fetchResource('/test')

    testMd = test.getMetaDataResource().getContent()
    testContent = test.getContent()

    cd,md = test_helper.TestMetaData(tester,
                                     testMd,
                                     'test',
                                     ResourceTypes.ResourceType.CONTAINER,
                                     [],
                                     tester.test_data['userName'],
                                     'text/xml',
                                     str(len(testContent)),
                                     []
                                     )

    test_helper.TestContainerRdf(tester,
                                 repo,
                                 test.getPath().absolutePath,
                                 len(testContent),
                                 tester.test_data['userName'],
                                 cd,
                                 md,
                                 ['foo'])
    repo.txRollback()
    tester.testDone()


    tester.startTest("Test Delete Empty")
    repo = test_helper.GetRepo(tester)
    repo.deleteResource('/test/foo/bar')
    tester.compare(0,repo.hasResource('/test/foo/bar'))
    repo.txCommit()

    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    tester.compare(0,test.hasResource('foo/bar'))
    repo.txRollback()
    tester.testDone()


    tester.startTest("Test Delete With Children")
    repo = test_helper.GetRepo(tester)
    foo = repo.fetchResource('/test/foo')
    test = foo.getParent()
    test.delete()
    tester.compare(0,repo.hasResource('/test/foo'))
    tester.compare(0,repo.hasResource('/test'))
    tester.testException(test.keys,(),FtServerServerException,{'code':Error.OBJECT_DELETED})
    tester.testException(foo.keys,(),FtServerServerException,{'code':Error.OBJECT_DELETED})
    repo.txCommit()

    repo = test_helper.GetRepo(tester)
    tester.compare(0,repo.hasResource('/test/foo'))
    tester.compare(0,repo.hasResource('/test'))
    repo.txRollback()

    tester.testDone()


# container models
# encoding: iso-8859-1
# important: whitespaces / tabs

from Ft.Server.Server.Drivers import FtssDriver
EMPTY_CONTAINER_CONTENT = FtssDriver._GetContainerXml([])
REPO_CONTAINER_CONTENT = FtssDriver._GetContainerXml([u'ftss', u'test'])

PARENT_CONTAINER_CONTENT="""<?xml version='1.0' encoding="ISO-8859-1"?><ftss:Container xmlns:xlink='%s' xmlns:ftss='%s'>\n  <ftss:Children><ftss:ChildReference xlink:href='%%s;metadata' xlink:type='simple' xlink:actuate='onLoad' xlink:show='embed'/></ftss:Children>\n</ftss:Container>""" % (XLINK_NAMESPACE, FTSERVER_NAMESPACE)

PARENT_CONTAINER_CONTENT = FtssDriver._GetContainerXml([u'%s'])





def cleanup(tester):

    tester.startTest("Clean Up")
    repo = test_helper.GetRepo(tester)
    if repo.hasResource('/test'):
        t = repo.fetchResource('/test')
        t.delete()
    repo.txCommit()
    tester.testDone()


def Test(tester):

    cleanup(tester)
    test_create(tester)
    test_access(tester)
    test_delete(tester)



