#!/usr/bin/python
import sys
import time
import os
import string
import StringIO
sys.path.append("python")
import libxml2


#
# the testsuite description
#
CONF="test/relaxng/OASIS/spectest.xml"
LOG="check-relaxng-test-suite.log"

log = open(LOG, "w")
nb_schemas_tests = 0
nb_schemas_success = 0
nb_schemas_failed = 0
nb_instances_tests = 0
nb_instances_success = 0
nb_instances_failed = 0

libxml2.lineNumbersDefault(1)
#
# Error and warnng callbacks
#
def callback(ctx, str):
    global log
    log.write("%s%s" % (ctx, str))

libxml2.registerErrorHandler(callback, "")

#
# Resolver callback
#
resources = {}
def resolver(URL, ID, ctxt):
    global resources

    if resources.has_key(URL):
        return(StringIO.StringIO(resources[URL]))
    log.write("Resolver failure: asked %s\n" % (URL))
    log.write("resources: %s\n" % (resources))
    return None

libxml2.setEntityLoader(resolver)

#
# handle a valid instance
#
def handle_valid(node, schema):
    global log
    global nb_instances_success
    global nb_instances_failed

    instance = ""
    child = node.children
    while child != None:
        if child.type != 'text':
	    instance = instance + child.serialize()
	child = child.next

    try:
	doc = libxml2.parseDoc(instance)
    except:
        doc = None

    if doc == None:
        log.write("\nFailed to parse correct instance:\n-----\n")
	log.write(instance)
        log.write("\n-----\n")
	nb_instances_failed = nb_instances_failed + 1
	return

    try:
        ctxt = schema.relaxNGNewValidCtxt()
	ret = doc.relaxNGValidateDoc(ctxt)
    except:
        ret = -1
    if ret != 0:
        log.write("\nFailed to validate correct instance:\n-----\n")
	log.write(instance)
        log.write("\n-----\n")
	nb_instances_failed = nb_instances_failed + 1
    else:
	nb_instances_success = nb_instances_success + 1

#
# handle an invalid instance
#
def handle_invalid(node, schema):
    global log
    global nb_instances_success
    global nb_instances_failed

    instance = ""
    child = node.children
    while child != None:
        if child.type != 'text':
	    instance = instance + child.serialize()
	child = child.next

    try:
	doc = libxml2.parseDoc(instance)
    except:
        doc = None

    if doc == None:
        log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
	log.write(instance)
        log.write("\n-----\n")
	return

    try:
        ctxt = schema.relaxNGNewValidCtxt()
	ret = doc.relaxNGValidateDoc(ctxt)
    except:
        ret = -1
    if ret == 0:
        log.write("\nFailed to detect validation problem in instance:\n-----\n")
	log.write(instance)
        log.write("\n-----\n")
	nb_instances_failed = nb_instances_failed + 1
    else:
	nb_instances_success = nb_instances_success + 1

#
# handle an incorrect test
#
def handle_correct(node):
    global log
    global nb_schemas_success
    global nb_schemas_failed

    schema = ""
    child = node.children
    while child != None:
        if child.type != 'text':
	    schema = schema + child.serialize()
	child = child.next

    try:
	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
	rngs = rngp.relaxNGParse()
    except:
        rngs = None
    if rngs == None:
        log.write("\nFailed to compile correct schema:\n-----\n")
	log.write(schema)
        log.write("\n-----\n")
	nb_schemas_failed = nb_schemas_failed + 1
    else:
	nb_schemas_success = nb_schemas_success + 1
    return rngs
        
def handle_incorrect(node):
    global log
    global nb_schemas_success
    global nb_schemas_failed

    schema = ""
    child = node.children
    while child != None:
        if child.type != 'text':
	    schema = schema + child.serialize()
	child = child.next

    try:
	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
	rngs = rngp.relaxNGParse()
    except:
        rngs = None
    if rngs != None:
        log.write("\nFailed to detect schema error in:\n-----\n")
	log.write(schema)
        log.write("\n-----\n")
	nb_schemas_failed = nb_schemas_failed + 1
    else:
#	log.write("\nSuccess detecting schema error in:\n-----\n")
#	log.write(schema)
#	log.write("\n-----\n")
	nb_schemas_success = nb_schemas_success + 1
    return None

#
# resource handling: keep a dictionary of URL->string mappings
#
def handle_resource(node, dir):
    global resources

    try:
	name = node.prop('name')
    except:
        name = None

    if name == None or name == '':
        log.write("resource has no name")
	return;
        
    if dir != None:
#        name = libxml2.buildURI(name, dir)
        name = dir + '/' + name

    res = ""
    child = node.children
    while child != None:
        if child.type != 'text':
	    res = res + child.serialize()
	child = child.next
    resources[name] = res

#
# dir handling: pseudo directory resources
#
def handle_dir(node, dir):
    try:
	name = node.prop('name')
    except:
        name = None

    if name == None or name == '':
        log.write("resource has no name")
	return;
        
    if dir != None:
#        name = libxml2.buildURI(name, dir)
        name = dir + '/' + name

    dirs = node.xpathEval('dir')
    for dir in dirs:
        handle_dir(dir, name)
    res = node.xpathEval('resource')
    for r in res:
        handle_resource(r, name)


#
# handle a testCase element
#
def handle_testCase(node):
    global nb_schemas_tests
    global nb_instances_tests
    global resources

    log.write("\n    ============= test %d line %d ================\n" % (

              nb_schemas_tests, node.lineNo()))
    resources = {}

    dirs = node.xpathEval('dir')
    for dir in dirs:
        handle_dir(dir, None)
    res = node.xpathEval('resource')
    for r in res:
        handle_resource(r, None)

    tsts = node.xpathEval('incorrect')
    if tsts != []:
        if len(tsts) != 1:
	    print "warning test line %d has more than one <incorrect> example" %(node.lineNo())
	schema = handle_incorrect(tsts[0])
    else:
        tsts = node.xpathEval('correct')
	if tsts != []:
	    if len(tsts) != 1:
		print "warning test line %d has more than one <correct> example"% (node.lineNo())
	    schema = handle_correct(tsts[0])
	else:
	    print "warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo())

    nb_schemas_tests = nb_schemas_tests + 1;
    
    valids = node.xpathEval('valid')
    invalids = node.xpathEval('invalid')
    nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
    if schema != None:
        for valid in valids:
	    handle_valid(valid, schema)
        for invalid in invalids:
	    handle_invalid(invalid, schema)


#
# handle a testSuite element
#
def handle_testSuite(node):
    docs = node.xpathEval('documentation')
    authors = node.xpathEval('author')
    if docs != []:
        msg = ""
        for doc in docs:
	    msg = msg + doc.content + " "
	if authors != []:
	    msg = msg + "written by "
	    for author in authors:
	        msg = msg + author.content + " "
	print msg
    sections = node.xpathEval('section')
    if sections != []:
        msg = ""
        for section in sections:
	    msg = msg + section.content + " "
        print "Tests for section %s" % (msg)
    for test in node.xpathEval('testCase'):
        handle_testCase(test)
    for test in node.xpathEval('testSuite'):
        handle_testSuite(test)
	        

#
# Parse the conf file
#
testsuite = libxml2.parseFile(CONF)
root = testsuite.getRootElement()
if root.name != 'testSuite':
    print "%s doesn't start with a testSuite element, aborting" % (CONF)
    sys.exit(1)
print "Running Relax NG testsuite"
handle_testSuite(root)

print "\nTOTAL:\nfound %d test schemas: %d success %d failures" % (
      nb_schemas_tests, nb_schemas_success, nb_schemas_failed)
print "found %d test instances: %d success %d failures" % (
      nb_instances_tests, nb_instances_success, nb_instances_failed)
