import sys

from Ft.Server.Common import CreationParams, ResourceTypes, Schema

import test_helper

def _MakeStatement(doc, pred, obj):
    path = doc.getAbsolutePath()
    return (path, pred, obj, '', 'ftss://'+path)

def test_create(tester):

    tester.startTest("Create a Document Definition")

    repo = test_helper.GetRepo(tester)
    ddRoot = repo.fetchResource('test')

    maps = [("$uri",'"NAME"',"//ft:name")]
    nss = {'ft':'foo.com'}
    dd = ddRoot.createXPathDocumentDefinition("def1",nss,maps,CreationParams.CreationParams())
    tester.testDone()

    tester.startTest("Create a Second Document Definition")
    maps = [("$uri",'"NAME2"',"//ft:name")]
    nss = {'ft':'foo.com'}
    dd2 = ddRoot.createXPathDocumentDefinition("def2",nss,maps,CreationParams.CreationParams())
    dd2.addBaseDocumentDefinition(dd)
    repo.txCommit()
    tester.testDone()


    tester.startTest("Get All Document Definition Uris")
    repo = test_helper.GetRepo(tester)
    names = repo.getAllDocumentDefinitionPaths()
    tester.compare(2, len(names))
    tester.compareIn(names, '/test/def1')
    tester.compareIn(names, '/test/def2')
    repo.txRollback()
    tester.testDone()

    return


def test_create_document(tester):

    tester.startTest("Create Document in base def")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.createDocument('DOC1',DOC1,docDef='/test/def1',forcedType=ResourceTypes.ResourceType.XML_DOCUMENT)

    dd = repo.fetchResource('test').fetchResource('def1')
    statements = [_MakeStatement(doc, 'NAME', 'Mike'),
                  _MakeStatement(doc, 'NAME', 'Uche'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   '/test/DOC1',
                                   len(DOC1),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   '/test/def1',
                                   docDefStmts=statements)
                           
    mds = dd.getMetaDocumentUris()
    tester.compare(1,len(mds))
    tester.compareIn(mds,doc.getPath().absolutePath)
    repo.txCommit()
    tester.testDone()


    tester.startTest("Fetch MetaDocument")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC1')
    dd = test.fetchResource('/test').fetchResource('def1')
    tester.compare(dd,doc.getDocumentDefinition())
    statements = [_MakeStatement(doc, 'NAME', 'Mike'),
                  _MakeStatement(doc, 'NAME', 'Uche'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   '/test/DOC1',
                                   len(DOC1),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   '/test/def1',
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()


    
    tester.startTest("Create Document in derived def")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')


    doc = test.createDocument('DOC2',DOC1,docDef='/test/def2',forcedType=ResourceTypes.ResourceType.XML_DOCUMENT)

    dd1 = test.fetchResource('/test').fetchResource('def1')
    dd = test.fetchResource('/test').fetchResource('def2')
    statements = [_MakeStatement(doc, 'NAME', 'Mike'),
                  _MakeStatement(doc, 'NAME', 'Uche'),
                  _MakeStatement(doc, 'NAME2', 'Mike'),
                  _MakeStatement(doc, 'NAME2', 'Uche'),
                  ]

    #model = repo.getModel()
    #print model.complete('/test/def2',None,None)
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   '/test/DOC2',
                                   len(DOC1),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getPath().absolutePath,
                                   docDefStmts=statements)
    repo.txCommit()
    tester.testDone()





def test_update_document(tester):

    tester.startTest("Update Document in base def")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC1')
    doc.setContent(DOC2)
    dd = test.fetchResource('/test').fetchResource('def1')
    statements = [_MakeStatement(doc, 'NAME', 'Vicki'),
                  _MakeStatement(doc, 'NAME', 'Stacey'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   '/test/DOC1',
                                   len(DOC2),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getPath().absolutePath,
                                   docDefStmts=statements)
    repo.txCommit()
    tester.testDone()

    tester.startTest("Fetch Modified Meta Document")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC1')
    dd = test.fetchResource('/test').fetchResource('def1')
    statements = [_MakeStatement(doc, 'NAME', 'Vicki'),
                  _MakeStatement(doc, 'NAME', 'Stacey'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   '/test/DOC1',
                                   len(DOC2),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getPath().absolutePath,
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()



    tester.startTest("Update Document in derived def")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC2')
    doc.setContent(DOC2)

    dd = test.fetchResource('/test').fetchResource('def2')
    dd1 = test.fetchResource('/test').fetchResource('def1')
    statements = [_MakeStatement(doc, 'NAME', 'Vicki'),
                  _MakeStatement(doc, 'NAME', 'Stacey'),
                  _MakeStatement(doc, 'NAME2', 'Vicki'),
                  _MakeStatement(doc, 'NAME2', 'Stacey'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   '/test/DOC2',
                                   len(DOC2),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getPath().absolutePath,
                                   docDefStmts=statements)
    repo.txCommit()
    tester.testDone()


def test_delete_document(tester):

    tester.startTest("Delete Document in base def")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC1')
    doc.delete()

    res = test.getModel().complete('/test/DOC1',None,None)
    tester.compare(0,len(res))
    tester.compare(0,test.hasResource('DOC1'))
    repo.txCommit()
    tester.testDone()

    tester.startTest("Delete Document in derived def")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC2')
    doc.delete()

    res = test.getModel().complete('/test/DOC2',None,None)
    tester.compare(0,len(res))
    tester.compare(0,test.hasResource('DOC2'))
    repo.txCommit()
    tester.testDone()


    tester.startTest("Removal of Meta Doc URIS")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    dd = test.fetchResource('/test').fetchResource('def2')
    dd1 = test.fetchResource('/test').fetchResource('def1')
    tester.compare(0,len(dd.getMetaDocumentUris()))
    tester.compare(0,len(dd1.getMetaDocumentUris()))
    repo.txCommit()
    tester.testDone()




def test_update(tester):

    tester.startTest("Recreate the deleted document")
    repo = test_helper.GetRepo(tester)    
    test = repo.fetchResource('/test')
    doc = test.createDocument('DOC1',DOC2,docDef='/test/def1',forcedType=ResourceTypes.ResourceType.XML_DOCUMENT)
    doc = test.createDocument('DOC2',DOC2,docDef='/test/def2',forcedType=ResourceTypes.ResourceType.XML_DOCUMENT)
    repo.txCommit()
    tester.testDone()

    tester.startTest("Update a Derived  Def")
    #Note, this should only modify DOC2

    repo = test_helper.GetRepo(tester)    
    ddRoot = repo.fetchResource('/test')

    maps = [("$uri",'"NEW_NAME1"',"//ft:name"),
            ("$uri",'"NEW_NAME2"',"$uri")]

    docDef = ddRoot.fetchResource('def2')
    docDef.setRdfMaps(maps)
    repo.txCommit()
    tester.testDone()


    tester.startTest("Test that the statements of DOC2 were modified")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC2')
    dd = test.fetchResource('def2')
    statements = [_MakeStatement(doc, 'NAME', 'Vicki'),
                  _MakeStatement(doc, 'NAME', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME2', doc.getAbsolutePath()),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getAbsolutePath(),
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()


    tester.startTest("Test that the statements of DOC1 were not modified")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC1')
    dd = test.fetchResource('def1')
    statements = [_MakeStatement(doc, 'NAME', 'Vicki'),
                  _MakeStatement(doc, 'NAME', 'Stacey'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getAbsolutePath(),
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()



    tester.startTest("Update a Base Def")
    #Note, this should modify DOC1, DOC2

    repo = test_helper.GetRepo(tester)    
    ddRoot = repo.fetchResource('/test')

    maps = [("$uri",'"NEW_NAME3"',"//ft:name"),
            ]

    docDef = ddRoot.fetchResource('def1')
    docDef.setRdfMaps(maps)
    repo.txCommit()
    tester.testDone()


    tester.startTest("Test that the statements of DOC2 were modified")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC2')
    dd = test.fetchResource('def2')
    statements = [_MakeStatement(doc, 'NEW_NAME3', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME3', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME2', doc.getAbsolutePath()),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getAbsolutePath(),
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()


    tester.startTest("Test that the statements of DOC1 were modified")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC1')
    dd = test.fetchResource('def1')
    statements = [_MakeStatement(doc, 'NEW_NAME3', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME3', 'Stacey'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getAbsolutePath(),
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()





def test_delete(tester):

    tester.startTest("Delete a Base Doc Def")
    repo = test_helper.GetRepo(tester)    
    ddRoot = repo.fetchResource('/test')
    ddRoot.deleteResource("def1")
    repo.txCommit()
    tester.testDone()


    tester.startTest("Test that the statements of DOC2 were modified")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC2')
    dd = test.fetchResource('def2')


    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getAbsolutePath(),
                                   docDefStmts=[_MakeStatement(doc, 'NEW_NAME1', 'Vicki'),
                                                _MakeStatement(doc, 'NEW_NAME1', 'Stacey'),
                                                _MakeStatement(doc, 'NEW_NAME2', doc.getAbsolutePath()),
                                                ]

                                   )
    repo.txRollback()
    tester.testDone()


    tester.startTest("Test that the statements of DOC1 were modified")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC1')
    statements = []
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   Schema.NULL_DOCDEF,
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()



    tester.startTest("Delete a Doc Def")
    repo = test_helper.GetRepo(tester)    
    ddRoot = repo.fetchResource('/test')
    ddRoot.deleteResource("def2")
    repo.txCommit()
    tester.testDone()


    tester.startTest("Test that the statements of DOC2 were modified")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource('/test')
    doc = test.fetchResource('DOC2')
    statements = []
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   Schema.NULL_DOCDEF,
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()







def test_inherits(tester):

    tester.startTest("Create another doc def")
    repo = test_helper.GetRepo(tester)    
    ddRoot = repo.fetchResource('/test')

    maps = [("$uri",'"NEW_NAME5"',"//ft:name")]
    nss = {'ft':'foo.com'}
    dd = ddRoot.createXPathDocumentDefinition("def3",nss,maps,CreationParams.CreationParams())
    dd1 = ddRoot.fetchResource('def2')
    repo.txCommit()
    tester.testDone()

    tester.startTest("Add Base to def2")
    repo = test_helper.GetRepo(tester)    
    ddRoot = repo.fetchResource('/test')
    dd2 = ddRoot.fetchResource('def2')
    dd3 = ddRoot.fetchResource('def3')
    dd2.addBaseDocumentDefinition(dd3)
    repo.txCommit()
    tester.testDone()


    tester.startTest("Test that DOC2 was updated")
    repo = test_helper.GetRepo(tester)    
    test = repo.fetchResource('test')
    doc = test.fetchResource('DOC2')
    dd = test.fetchResource('def2')
    statements = [_MakeStatement(doc, 'NEW_NAME3', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME3', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME2', doc.getAbsolutePath()),
                  _MakeStatement(doc, 'NEW_NAME5', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME5', 'Stacey'),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getAbsolutePath(),
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()


    tester.startTest("Remove Base")
    repo = test_helper.GetRepo(tester)    
    ddRoot = repo.fetchResource('/test')
    dd2 = ddRoot.fetchResource('def2')
    dd3 = ddRoot.fetchResource('def3')
    dd2.removeBaseDocumentDefinition(dd3)
    repo.txCommit()
    tester.testDone()


    tester.startTest("Test that DOC2 was updated")
    repo = test_helper.GetRepo(tester)    
    test = repo.fetchResource('test')
    doc = test.fetchResource('DOC2')
    dd = test.fetchResource('def2')
    statements = [_MakeStatement(doc, 'NEW_NAME3', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME3', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Vicki'),
                  _MakeStatement(doc, 'NEW_NAME1', 'Stacey'),
                  _MakeStatement(doc, 'NEW_NAME2', doc.getAbsolutePath()),
                  ]
    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getAbsolutePath(),
                                   len(doc.getContent()),
                                   tester.test_data['userName'],
                                   None,
                                   None,
                                   'text/xml',
                                   dd.getAbsolutePath(),
                                   docDefStmts=statements)
    repo.txRollback()
    tester.testDone()




def test_clean(tester):

    tester.startTest("clean Document Definition")


    repo = test_helper.GetRepo(tester)

    if repo.hasResource('/test'):
        t = repo.fetchResource('/test')
        t.delete()
    repo.createContainer("/test", 1)

    repo.txCommit()
    tester.testDone()


DOC1="""<?xml version = "1"?><foo xmlns:ft = 'foo.com'><ft:name>Mike</ft:name><ft:name>Uche</ft:name></foo>"""
DOC2="""<?xml version = "1"?><foo xmlns:ft = 'foo.com'><ft:name>Vicki</ft:name><ft:name>Stacey</ft:name></foo>"""

def Test(tester):
    test_clean(tester)
    test_create(tester)

    test_create_document(tester)
    test_update_document(tester)
    test_delete_document(tester)
    test_update(tester)
    test_inherits(tester)
    test_delete(tester)
    test_clean(tester)

