#!/usr/bin/python

import sys
import string
import re
from xmllib_NO_NS import XMLParser
from URLProcessor import URLProcessor
import returnXML
import os.path
from XmlCGI import xmlCgi
from os import pipe
from os import environ
from popen2 import popen2
from threading import Thread, Lock

class PIProcessor(XMLParser):
    def __init__(self,lines):
        XMLParser.__init__(self)
        self.linePointer=0
        self.foundPI=0
        self.lines=lines
        self.callToolLock=Lock()
        self.callToolWaitForThread=Lock()
        
    def process(self):
        for x in self.lines:
            self.feed(x+"\n")
            if self.foundPI:
                break
            self.linePointer=self.linePointer+1

    def handle_proc(self, name, data):
        global FILE_TO_PROCESS
        self.foundPI=1
        if name == "return":
            #######################################################
            ### LOOK AT self.rawdata[4+len(name)+len(data):] 
            ### THIS IS EXTREMELY HACHY AND A REASON FOR USING SAX
            #######################################################
            print returnXML.returnXMLContent(data,
                                             self.rawdata[4+len(name)+len(data):]+self.contentWithoutProcessedLine())
            sys.exit(0)
        elif name == "URLProcessor":
            p = URLProcessor()
            p.feed(self.contentWithoutProcessedLine())
            FILE_TO_PROCESS=""
            processPIsRec(p.render.RESULT)
        elif name == "cgi":
            FILE_TO_PROCESS=""
            processPIsRec(self.contentWithoutProcessedLine()+xmlCgi())
        elif name == "callTool":
            FILE_TO_PROCESS=""
            self.callTool(data,self.contentWithoutProcessedLine())
        elif name == "xml-stylesheet":
            if FILE_TO_PROCESS:
                # print "<!-- #####"+FILE_TO_PROCESS+"-->"
                self.callTool("xalan -IN "+FILE_TO_PROCESS,"")
            else:
                self.callTool("xslt "+rectifiedXMLStylesheetHREF(data)
                              ,self.contentWithoutProcessedLine())
        else:
            self.foundPI=0
        
    def contentWithoutProcessedLine(self):
        return lines2String(self.lines[:self.linePointer]+self.lines[self.linePointer+1:])
            
    def callTool(self, cmd, content):
        global PROCESS_BASE_DIR
        cmd=string.strip(cmd)
        self.callToolLock.acquire()
        self.callToolWaitForThread.acquire()
        (child_stdout, child_stdin) = popen2(PROCESS_BASE_DIR+"tools/"+cmd)
        def ri(slf,o):
            slf.RES=o.read()
            slf.callToolWaitForThread.release()
        t=Thread(target=ri,args=(self,child_stdout))
        t.start()
        child_stdin.write(content)
        child_stdin.close()
        self.callToolWaitForThread.acquire()
        self.callToolWaitForThread.release()
        self.callToolLock.release()
        processPIsRec(self.RES)

def lines2String(arrayOfLines):
    RES=""
    for ln in arrayOfLines:
        RES=RES+ln+"\n"
    return RES

def rectifiedXMLStylesheetHREF(txt):
    global FILE_TO_PROCESS_BASEDIR
    hrefFound=-1
    for x in re.split('"',txt):
        if hrefFound>=0:
            if string.find(x,"/")==0:
                return x
            elif string.find(x,"://")>=0:
                return x
            else:
                return FILE_TO_PROCESS_BASEDIR+"/"+x
        hrefFound=string.find(x,"href")

def processPIsRec(data):
    p = PIProcessor(string.split(data,"\n"))
    p.process()
    if not p.foundPI:
        for ln in p.lines:
            print ln

# The 2nd attemp to provide a perfect processing tool works different
# The problem was concerned to either hanging in an endless loop when xalan tried to
# fetch the URL (because process reexecuted the same Document) or
# not having the right baseurl when using the fileaccess to documents.
# This Version tries to solve this problem by using a little key in
# the HTTP-Request.
if __name__ == '__main__':
    global PROCESS_BASE_DIR
    global FILE_TO_PROCESS
    global FILE_TO_PROCESS_BASEDIR
    PROCESS_BASE_DIR=os.path.dirname(sys.argv[0])+"/../"

    #    if environ.has_key("HTTP_HOST"):
    #    USE_HTTP_PREFIX="http://"+environ["HTTP_HOST"]+os.path.dirname(os.environ["SCRIPT_NAME"])+"/"
    #else:
    #    USE_HTTP_PREFIX=""
    USE_HTTP=""

    if len(sys.argv)==1:
        # This block is used when piping in some content.
        # In this case the script considers to be used in a local context.
        # The baseURL is set to the actual working directory.
        FILE_TO_PROCESS=""
        processPIsRec(sys.stdin.read())
    else:
        # This block maybe was called through a webserver. Therefore we need to check
        # this context. Therefore if we call a document for e.g. processing it through
        # the xslt processor, we need to tell the new process2 instance to bypass any processing 
        # activity.
        if USE_HTTP:
            FILE_TO_PROCESS=USE_HTTP_PREFIX+os.path.basename(sys.argv[1])
        else:
            FILE_TO_PROCESS=sys.argv[1]
        FILE_TO_PROCESS_BASEDIR=os.path.dirname(os.path.abspath(sys.argv[1]))
        processPIsRec(open(sys.argv[1],"r").read())

