
import string, urlparse
from Ft.Server.Server.Drivers import PathImp

from Ft.Server.Common import Schema, ResourceTypes

class FakeDriver:
    def __init__(self):
        from Ft.Rdf.Drivers import Memory
        from Ft.Rdf import Model,Statement, RDF_MS_BASE
        d = Memory.DbAdapter('')
        d.begin()
        self._model = Model.Model(d)
        self._model.add([Statement.Statement('/alias',
                                             Schema.TYPE,
                                             Schema.g_rdfResourceTypes[ResourceTypes.ResourceType.ALIAS]),
                         Statement.Statement('/alias',
                                             Schema.ALIAS_REFERENCE,
                                             '/test'),
                         Statement.Statement('/test/foo/subalias',
                                             Schema.TYPE,
                                             Schema.g_rdfResourceTypes[ResourceTypes.ResourceType.ALIAS]),
                         Statement.Statement('/test/foo/subalias',
                                             Schema.ALIAS_REFERENCE,
                                             '/bar'),
                         Statement.Statement('/a1',
                                             Schema.TYPE,
                                             Schema.g_rdfResourceTypes[ResourceTypes.ResourceType.ALIAS]),
                         Statement.Statement('/a1',
                                             Schema.ALIAS_REFERENCE,
                                             '/a2'),
                         Statement.Statement('/a2',
                                             Schema.TYPE,
                                             Schema.g_rdfResourceTypes[ResourceTypes.ResourceType.ALIAS]),
                         Statement.Statement('/a2',
                                             Schema.ALIAS_REFERENCE,
                                             '/dest'),

                         Statement.Statement('/far-alias',
                                             Schema.TYPE,
                                             Schema.g_rdfResourceTypes[ResourceTypes.ResourceType.ALIAS]),
                         Statement.Statement('/far-alias',
                                             Schema.ALIAS_REFERENCE,
                                             '/test/test/test/test/test'),
                         ])
        


    def getSystemModel(self):
        return self._model
        


def _test_path(tester,pathString,absString,path,aPaths = None, rt = None):


    scheme, netloc, testString, params, query, fragment = urlparse.urlparse(pathString)

    dSteps = ['/'] + filter(None,string.split(testString,'/'))
    aSteps = ['/'] + filter(None,string.split(absString,'/'))

    dPaths = ['/']
    cur = ''
    for s in dSteps[1:]:
        cur = cur + '/' + s
        dPaths.append(cur)

    if aPaths is None:
        aPaths = ['/']
        cur = ''
        for s in aSteps[1:]:
            cur = cur + '/' + s
            aPaths.append(cur)


    #content, no-traverse and traverse are never in the display path
    dPath = "".join(pathString.split(';no-traverse'))
    dPath = "".join(dPath.split(';traverse'))
    dPath = "".join(dPath.split(';content'))

    tester.compare(dPath,path.displayPath)
    tester.compare(absString,path.absolutePath)

    tester.compare(len(dSteps),len(path.displaySteps))
    for d in path.displaySteps:
        tester.compareIn(dSteps,d)

    tester.compare(len(dPaths),len(path.displayPaths))
    for d in path.displayPaths:
        tester.compareIn(dPaths,d)

    tester.compare(len(aPaths),len(path.absolutePaths))
    for a in path.absolutePaths:
        tester.compareIn(aPaths,a)

    tester.compare(rt,path.resourceType)


def test_create(tester):

    tester.startTest("Create Initial Path Object")
    path = PathImp.CreateInitialPath('/',FakeDriver())
    _test_path(tester,'/','/',path,rt=ResourceTypes.RESOURCE_CONTENT)
    tester.testDone()


def test_simple(tester):


    for suffix, typ in [('',ResourceTypes.RESOURCE_CONTENT),
                        (';content',ResourceTypes.RESOURCE_CONTENT),
                        (';metadata',ResourceTypes.RESOURCE_METADATA),
                        (';cache',ResourceTypes.RESOURCE_CACHE),
                        (';content;no-traverse',ResourceTypes.RESOURCE_CONTENT),
                        (';metadata;no-traverse',ResourceTypes.RESOURCE_METADATA),
                        (';cache;no-traverse',ResourceTypes.RESOURCE_CACHE),
                        (';content;traverse',ResourceTypes.RESOURCE_CONTENT),
                        (';metadata;traverse',ResourceTypes.RESOURCE_METADATA),
                        (';cache;traverse',ResourceTypes.RESOURCE_CACHE)
                        ]:


        tester.startGroup("Simple Expression with suffix '%s'" % (suffix))
        root = PathImp.CreateInitialPath('/',FakeDriver())

        for sPath,exp,aExp in [("/","/",'/'),
                               ('//','/','/'),
                               ('/test','/test','/test'),
                               ('//test','/test','/test'),
                               ('test','/test','/test'),
                               ]:
            tester.startTest(sPath+suffix)
            path = root.normalize(sPath+suffix)
            _test_path(tester,exp+suffix,aExp,path,rt = typ)
            tester.testDone()

        #path = '/test'
        for sPath,exp,aExp in [#("foo","/test/foo",'/test/foo'),
                               ('/foo','/foo','/foo'),
                               ('////foo','/foo','/foo'),
                               ('foo/bar','/test/foo/bar','/test/foo/bar'),
                               ('foo//bar','/test/foo/bar','/test/foo/bar'),
                               ('.','/test','/test'),
                               ('./.','/test','/test'),
                               ('..','/','/'),
                               ('../..','/','/'),
                               ('foo/bar/../..','/test','/test'),
                               ('foo/bar/../../..','/','/'),
                               ('foo/../bar/..','/test','/test'),
                               ('foo/./.././bar/..','/test','/test'),
                               ]:
            tester.startTest(sPath+suffix)
            nPath = path.normalize(sPath+suffix)
            _test_path(tester,exp+suffix,aExp,nPath,rt=typ)
            tester.testDone()


        tester.groupDone()

def test_aliases(tester):
    tester.startGroup("Test with aliases")

    #Note dr/alias is an alias to /test
    #/test/foo/subalias is an alias /bar
    #dr/a1 --> /a2 --> dest

    root = PathImp.CreateInitialPath('/',FakeDriver())
    path = root.normalize('/test')
    #path = '/test'

    for suffix, typ in [('',ResourceTypes.RESOURCE_CONTENT),
			(';traverse',ResourceTypes.RESOURCE_CONTENT),
                        (';content;traverse',ResourceTypes.RESOURCE_CONTENT),
                        (';metadata;traverse',ResourceTypes.RESOURCE_METADATA),
                        (';cache;traverse',ResourceTypes.RESOURCE_CACHE)
                        ]:


        for sPath,exp,aExp,aPaths in [("/alias","/alias",'/test',['/','/test']),
                                      ("/alias/foo","/alias/foo",'/test/foo',['/','/test','/test/foo']),
                                      ("/alias/foo/subalias","/alias/foo/subalias",'/bar',['/','/test','/test/foo','/bar']),
                                      ("/alias/..","/",'/',['/']),
                                      ("/alias/foo/subalias/..","/alias/foo",'/test/foo',['/','/test','/test/foo']),
                                      ("/alias/foo/subalias/../../..","/",'/',['/']),
                                      ("/a1","/a1",'/dest',['/','/dest']),
                                      ("/a1/..","/",'/',['/']),
                                      ("/a1/baz","/a1/baz",'/dest/baz',['/','/dest','/dest/baz']),
                                      ("/far-alias",
                                       "/far-alias",
                                       '/test/test/test/test/test',
                                       ['/','/test/test/test/test/test']),
                                      ("/far-alias/baz",
                                       "/far-alias/baz",
                                       '/test/test/test/test/test/baz',
                                       ['/','/test/test/test/test/test','/test/test/test/test/test/baz']),
                                      ("/far-alias/..","/",'/',['/']),
                                      ("/far-alias/../alias/foo/subalias","/alias/foo/subalias",'/bar',['/','/test','/test/foo','/bar']),
                                      ]:
            tester.startTest(sPath+suffix)
            nPath = path.normalize(sPath+suffix)
            _test_path(tester,exp+suffix,aExp,nPath,aPaths,typ)
            tester.testDone()

    tester.groupDone()

def test_aliases_no_traverse(tester):
    tester.startGroup("Test with aliases sans last traverse")

    #Note dr/alias is an alias to /test
    #/test/foo/subalias is an alias /bar
    #dr/a1 --> /a2 --> dest
 

    root = PathImp.CreateInitialPath('/',FakeDriver())
    path = root.normalize('/test;no-traverse')
    #path = '/test'

    for suffix, typ in [(';no-traverse',ResourceTypes.RESOURCE_CONTENT),
                        (';content;no-traverse',ResourceTypes.RESOURCE_CONTENT),
                        (';metadata;no-traverse',ResourceTypes.RESOURCE_METADATA),
                        (';cache;no-traverse',ResourceTypes.RESOURCE_CACHE)
                        ]:


        for sPath,exp,aExp,aPaths in [("/alias","/alias",'/alias',['/','/alias']),
                                      ("/alias/foo","/alias/foo",'/test/foo',['/','/test','/test/foo']),
                                      ("/alias/foo/subalias","/alias/foo/subalias",'/test/foo/subalias',['/','/test','/test/foo','/test/foo/subalias']),
                                      ]:
            tester.startTest(sPath+suffix)
            nPath = path.normalize(sPath+suffix)
            _test_path(tester,exp+suffix,aExp,nPath,aPaths,typ)
            tester.testDone()

    tester.groupDone()


def Test(tester):

    tester.startGroup("Path")
    test_create(tester)
    test_simple(tester)
    test_aliases(tester)
    test_aliases_no_traverse(tester)
    tester.groupDone()
