from Ft.Server.Server import FtServerServerException, Error
from Ft.Server.Common import ResourceTypes, Schema, ValidationInfo
from Ft.Xml.Xslt import Stylesheet

import time
import test_helper

def test_create_xinc(tester):
    tester.startGroup("Create XML document with xinclude")

    #Create XML Document
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource("/test")

    tester.startTest("Simple XInclude")
    doc = test.createDocument(
        'include1.xml', INC1, forcedType=ResourceTypes.ResourceType.XML_DOCUMENT
        )

    doc = test.createDocument(
        'include2.xml', INC2, forcedType=ResourceTypes.ResourceType.XML_DOCUMENT
        )
    tester.compare('foo',doc.asDom().documentElement.childNodes[1].localName)

    
    doc = test.createDocument(
        'xi_doc1', XI_DOC1, forcedType=ResourceTypes.ResourceType.XML_DOCUMENT
        )
    tester.compare('foo',doc.asDom().documentElement.childNodes[1].localName)

    doc = test.createDocument(
        'xi_doc2', XI_DOC2, forcedType=ResourceTypes.ResourceType.XML_DOCUMENT
        )

    tester.compare('foo',doc.asDom().documentElement.childNodes[1].localName)

    doc = test.createDocument(
        'xi_doc3', XI_DOC3, forcedType=ResourceTypes.ResourceType.XML_DOCUMENT
        )
    tester.compare(2,len(doc.asDom().documentElement.childNodes))

    doc = test.createDocument(
        'ent_doc1', ENT_DOC1, forcedType=ResourceTypes.ResourceType.XML_DOCUMENT
        )
    tester.compare('foo',doc.asDom().documentElement.childNodes[2].localName)

    repo.txRollback()
    tester.testDone()
    tester.groupDone()


def test_create(tester):
    tester.startTest("Create XML Document")

    #Create XML Document
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource("/test")

    doc = test.createDocument(
        'doc1', DOC1, forcedType=ResourceTypes.ResourceType.XML_DOCUMENT
        )

    dMd = doc.getMetaDataResource().getContent()
    dContent = doc.getContent()

    cd, md = test_helper.TestMetaData(tester, dMd, 'doc1',
                                     ResourceTypes.ResourceType.XML_DOCUMENT,
                                     [], tester.test_data['userName'],
                                     'text/xml', str(len(dContent)), [],
                                     )

    tester.compare(DOC1, dContent)

    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getPath().absolutePath,
                                   len(dContent),
                                   tester.test_data['userName'],
                                   cd,
                                   md,
                                   'text/xml',
                                   Schema.NULL_DOCDEF)

    tester.compare(ResourceTypes.ResourceType.XML_DOCUMENT,test.hasResource('doc1'))
    tester.compare(doc,test.fetchResource('doc1'))

    tester.compare(ResourceTypes.ResourceType.XML_DOCUMENT,doc.getResourceType())
    tester.compare(1,doc.isResourceType(ResourceTypes.ResourceType.RAW_FILE))
    tester.compare(1,doc.isResourceType(ResourceTypes.ResourceType.XML_DOCUMENT))
    tester.compare(0,doc.isResourceType(ResourceTypes.ResourceType.CONTAINER))
    repo.txCommit()

    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource("/test")
    tester.compare(ResourceTypes.ResourceType.XML_DOCUMENT,test.hasResource('doc1'))
    repo.txRollback()

    repo = test_helper.GetRepo(tester)
    doc = repo.fetchResource("/test/doc1")
    test = repo.fetchResource('/test')
    tester.compare(test,doc.getParent())
    repo.txRollback()
                   
    tester.testDone()
    return




def test_access(tester):

    tester.startTest("XML Document Access")

    repo = test_helper.GetRepo(tester)
    doc = repo.fetchResource("/test/doc1")

    dMd = doc.getMetaDataResource().getContent()
    dContent = doc.getContent()


    cd,md = test_helper.TestMetaData(tester,
                                     dMd,
                                     'doc1',
                                     ResourceTypes.ResourceType.XML_DOCUMENT,
                                     [],
                                     tester.test_data['userName'],
                                     'text/xml',
                                     str(len(dContent)),
                                     [],
                                     )

    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getPath().absolutePath,
                                   len(dContent),
                                   tester.test_data['userName'],
                                   cd,
                                   md,
                                   'text/xml',
                                   Schema.NULL_DOCDEF)

    tester.compare('text/xml',doc.getImt())
    tester.compare(DOC1,doc.getContent())
    test_helper.CompareValidationInfo(tester,ValidationInfo.NoValidation(),doc.getValidationInfo())
    #Just call, don't test
    doc.getCreationDate()
    doc.getLastModifiedDate()

    repo.txRollback()
    
    tester.testDone()


def test_modify(tester):

    tester.startTest("XML Document Modification")


    repo = test_helper.GetRepo(tester)
    doc = repo.fetchResource("/test/doc1")
    lmd = doc.getLastModifiedDate()
    time.sleep(1)
    doc.setContent(DOC2)

    dMd = doc.getMetaDataResource().getContent()
    dContent = doc.getContent()

    cd,md = test_helper.TestMetaData(tester,
                                     dMd,
                                     'doc1',
                                     ResourceTypes.ResourceType.XML_DOCUMENT,
                                     [],
                                     tester.test_data['userName'],
                                     'text/xml',
                                     str(len(dContent)),
                                     [],
                                     )

    test_helper.TestXmlDocumentRdf(tester,
                                   repo,
                                   doc.getPath().absolutePath,
                                   len(dContent),
                                   tester.test_data['userName'],
                                   cd,
                                   md,
                                   'text/xml',
                                   Schema.NULL_DOCDEF)

    tester.compare(DOC2,doc.getContent())
    repo.txCommit()

    repo = test_helper.GetRepo(tester)
    doc = repo.fetchResource("/test/doc1")
    tester.compare(DOC2,doc.getContent())
    tester.compare(1,doc.getLastModifiedDate() > lmd)
    repo.txRollback()
    
    tester.testDone()


def test_delete(tester):

    tester.startTest("Delete XML Document")
    repo = test_helper.GetRepo(tester)
    doc = repo.fetchResource("/test/doc1")
    fp = doc.getPath().absolutePath
    test = doc.getParent()
    doc.delete()
    tester.compare(0,test.hasResource('doc1'))
    tester.compare(0,len(repo.getModel().complete(fp,None,None)))
    tester.testException(doc.getContent,(),FtServerServerException,{'code':Error.OBJECT_DELETED})
    repo.txCommit()

    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource("/test")
    tester.compare(0,test.hasResource('doc1'))
    tester.compare(0,len(repo.getModel().complete(fp,None,None)))
    repo.txRollback()

    tester.testDone()

def test_xml_interfaces(tester):

    tester.startTest("XML Document to DOM")
    repo = test_helper.GetRepo(tester)
    test = repo.fetchResource("/test")
    doc1 = test.createDocument('doc1',DOC1,forcedType=ResourceTypes.ResourceType.XML_DOCUMENT)

    dom = doc1.asDom()
    tester.compare('docelem',dom.documentElement.nodeName)
    repo.txCommit()
    tester.testDone()


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


DOC1="""<docelem v='foo'/>"""
DOC2="""<docelem w='foo'/>"""

INC1 = """<?xml version='1.0' encoding='utf-8'?>
<foo/>
"""

INC2 = """<?xml version='1.0' encoding='utf-8'?>
<foo xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="include1.xml"/>
</foo>
"""

XI_DOC1 = """<?xml version='1.0'?>
<x xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="include1.xml"/>
</x>
"""

XI_DOC2 = """<?xml version='1.0'?>
<x xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="include2.xml"/>
</x>
"""

XI_DOC3 = """<?xml version='1.0'?>
<x xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="include1.xml" parse='text'/>
</x>
"""

ENT_DOC1 = """<?xml version='1.0'?>
<!DOCTYPE a [
  <!ENTITY foo SYSTEM "include1.xml">
]>
<a>
  Testing &foo; testing
</a>
"""

SHEET1 = """<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
  Sheet 1
  </xsl:template>
</xsl:stylesheet>"""

SCHEMA1="""<schema xmlns='http://www.ascc.net/xml/schematron'>
    
  <pattern name='Root'>
    <rule context="/docelem">
      <assert test='@v'>
        VALIDATION ERROR: The root element must have a v attribute
      </assert>      
    </rule>
  </pattern>
  
</schema>"""


def Test(tester):
    cleanup(tester)
    test_create(tester)
    test_create_xinc(tester)
    test_access(tester)
    test_modify(tester)
    test_delete(tester)
    test_xml_interfaces(tester)

