#!/usr/bin/python
#
# examples.py - SPARQL Protocol Spec Example Generator 
#

import os, sys, string, getopt
import RDF, SimpleRDF, Vocabulary
import sparqlclient, sparqlprottests
import rdfdiff
import xmltramp

from sparqlprottests import *
from StringIO import StringIO
from xml.sax import saxutils
from xmltramp import Element

RDF.debug(0)
SimpleRDF.debug(0)

def usage():
    print """
Usage: %s [OPTIONS]

Standard arguments:

    -v              Verbose; display verbose debugging messages.
    -t, --test-only For debugging use only, does not print actual output, implies -v.
    -d, --data      Directory containing test manifest.ttl files.
    -f, --file      Path to specification file.
    -l, --location  URL Location of specification.
    -h, --help      Display this help message.

Examples:

    python examples.py -f ../../proto-wd/Overview.html

    or

    python examples.py -l http://www.w3.org/2001/sw/DataAccess/proto-wd/ 
    
        """ % sys.argv[:1].pop()

def main():

    verbose = False
    test = False
    location = None
    file = None
    data = "../data"

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hf:dl:vt", ["test-only", "data=", "file=", "location=", "help"])
        if len(sys.argv[1:]) == 0:
            raise getopt.GetoptError("")
    except getopt.GetoptError:
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
        elif opt in ('-d', '--data'):
            data = arg
        elif opt in ('-l', '--location'):
            location = arg
        elif opt in ('-v'):
            verbose = True
        elif opt in ('-t', '--test-only'):
            verbose = True
            test = True
        elif opt in ('-f', '--file'):
            file = arg

    if not (file or location):
        print "\nPlease specifiy either a file or location."
        usage()
        sys.exit(2)
        
    if verbose: 
        import httplib
        httplib.HTTPConnection.debuglevel = 1

    contents = None
    if file:
        contents = open(file, "r")
    elif location:
        import urllib
        contents = urllib.urlopen(location)

    html = contents.read()
    contents = StringIO(html)

    entries = dict([ (str(entry["name"]), entry) for entry in sparqlprottests.load_tests(os.path.abspath(data)) ])

    h = xmltramp.Namespace("http://www.w3.org/1999/xhtml")

    tree = xmltramp.seed(contents)
    for e in walk(tree):
        if e._name == h.div:
            try:
                pres = e[h.pre:]
                if len(pres) == 3:
                    exid = e('id').replace('div-','')
                    if entries.has_key(exid):

                        print "\n-----------------------------------------\n"

                        entry = entries[exid]

                        for pre in pres:
                            if pre('class') == "query":
                                
                                print "@@found: %s query" % str(entry["name"])

                                specquery = str(pre)
                                testquery = " ".join(entry.get_query(translate=False).split())

                                if not specquery == testquery:
                                    print "ERROR: queries do not match"
                                    print "\tspec: %s" % specquery
                                    print "\ttest: %s" % testquery

                                try:
                                    query = RDF.SPARQLQuery(testquery)
                                    query.execute(RDF.Model())
                                except Exception, value:
                                    if str(value).find("syntax") > -1:
                                        print "ERROR: %s" % value
                                        print "\tquery: %s" % testquery
            
            except KeyError:
                pass


    sys.exit(2)

def walk(xt):
    """iterate over xt and its subelements"""
    yield xt
    for child in xt._dir:
        if isinstance(child, Element):
            for ch in walk(child): yield ch
        
if __name__ == "__main__":
    main()
