# *************************************************************
#  
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#  
#    http://www.apache.org/licenses/LICENSE-2.0
#  
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.
#  
# *************************************************************

# XScript implementation for python
import uno
import unohelper
import sys
import os
import imp
import time
import ast

try:
    unicode
except NameError:
    unicode = str

class LogLevel:
    NONE = 0   # production level
    ERROR = 1  # for script developers
    DEBUG = 2  # for script framework developers

PYSCRIPT_LOG_ENV = "PYSCRIPT_LOG_LEVEL"
PYSCRIPT_LOG_STDOUT_ENV = "PYSCRIPT_LOG_STDOUT"

# Configuration ----------------------------------------------------
LogLevel.use = LogLevel.NONE
if os.environ.get(PYSCRIPT_LOG_ENV) == "ERROR":
    LogLevel.use = LogLevel.ERROR
elif os.environ.get(PYSCRIPT_LOG_ENV) == "DEBUG":
    LogLevel.use = LogLevel.DEBUG

# True, writes to stdout (difficult on windows)
# False, writes to user/Scripts/python/log.txt
LOG_STDOUT = os.environ.get(PYSCRIPT_LOG_STDOUT_ENV, "1") != "0"

ENABLE_EDIT_DIALOG=False                    # offers a minimal editor for editing.
#-------------------------------------------------------------------

def encfile(uni):
    return uni.encode( sys.getfilesystemencoding())

def lastException2String():
    (excType,excInstance,excTraceback) = sys.exc_info()
    ret = str(excType) + ": "+str(excInstance) + "\n" + \
          uno._uno_extract_printable_stacktrace( excTraceback )
    return ret

def logLevel2String( level ):
    ret = " NONE"
    if level == LogLevel.ERROR:
        ret = "ERROR"
    elif level >= LogLevel.DEBUG:
        ret = "DEBUG"
    return ret

def getLogTarget():
    ret = sys.stdout
    if not LOG_STDOUT:
        try:
            pathSubst = uno.getComponentContext().ServiceManager.createInstance(
                "com.sun.star.util.PathSubstitution" )
            userInstallation =  pathSubst.getSubstituteVariableValue( "user" )
            if len( userInstallation ) > 0:
                systemPath = uno.fileUrlToSystemPath( userInstallation + "/Scripts/python/log.txt" )
                ret = file( systemPath , "a" )
        except Exception as e:
            print("Exception during creation of pythonscript logfile: "+ lastException2String() + "\n, delagating log to stdout\n")
    return ret

class Logger(LogLevel):
    def __init__(self , target ):
        self.target = target

    def isDebugLevel( self ):
        return self.use >= self.DEBUG

    def debug( self, msg ):
        if self.isDebugLevel():
            self.log( self.DEBUG, msg )

    def isErrorLevel( self ):
        return self.use >= self.ERROR

    def error( self, msg ):
        if self.isErrorLevel():
            self.log( self.ERROR, msg )

    def log( self, level, msg ):
        if self.use >= level:
            try:
                self.target.write(
                    time.asctime() +
                    " [" +
                    logLevel2String( level ) +
                    "] " +
                    encfile(msg) +
                    "\n" )
                self.target.flush()
            except Exception as e:
                print("Error during writing to stdout: " +lastException2String() + "\n")

log = Logger( getLogTarget() )

log.debug( "pythonscript loading" )

#from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider
from com.sun.star.uno import RuntimeException
from com.sun.star.lang import XServiceInfo
from com.sun.star.io import IOException
from com.sun.star.ucb import CommandAbortedException, XCommandEnvironment, XProgressHandler, Command
from com.sun.star.task import XInteractionHandler
from com.sun.star.beans import XPropertySet, Property
from com.sun.star.container import XNameContainer
from com.sun.star.xml.sax import XDocumentHandler, InputSource
from com.sun.star.uno import Exception as UnoException
from com.sun.star.script import XInvocation
from com.sun.star.awt import XActionListener

from com.sun.star.script.provider import XScriptProvider, XScript, XScriptContext, ScriptFrameworkErrorException
from com.sun.star.script.browse import XBrowseNode
from com.sun.star.script.browse.BrowseNodeTypes import SCRIPT, CONTAINER, ROOT
from com.sun.star.util import XModifyListener

LANGUAGENAME = "Python"
GLOBAL_SCRIPTCONTEXT_NAME = "XSCRIPTCONTEXT"
CALLABLE_CONTAINER_NAME =  "g_exportedScripts"

# pythonloader looks for a static g_ImplementationHelper variable
g_ImplementationHelper = unohelper.ImplementationHelper()
g_implName = "org.openoffice.pyuno.LanguageScriptProviderFor"+LANGUAGENAME



BLOCK_SIZE = 65536
def readTextFromStream( inputStream ):
    # read the file
    code = uno.ByteSequence( "" )
    while True:
        read,out = inputStream.readBytes( None , BLOCK_SIZE )
        code = code + out
        if read < BLOCK_SIZE:
            break
    return code.value

def toIniName( str ):
    # TODO: what is the official way to get to know whether i am on the windows platform ?
    if( hasattr(sys , "dllhandle") ):
        return str + ".ini"
    return str + "rc"


""" definition: storageURI is the system dependent, absolute file url, where the script is stored on disk
                scriptURI is the system independent uri
"""
class MyUriHelper:

    def __init__( self, ctx, location ):
        self.s_UriMap = \
        { "share" : "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" +  toIniName( "bootstrap") + "::BaseInstallation}/share/Scripts/python" , \
          "share:uno_packages" : "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages", \
          "user" : "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" + toIniName( "bootstrap") + "::UserInstallation}/user/Scripts/python" , \
          "user:uno_packages" : "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages" }
        self.m_uriRefFac = ctx.ServiceManager.createInstanceWithContext("com.sun.star.uri.UriReferenceFactory",ctx)
        if location.startswith( "vnd.sun.star.tdoc" ):
            self.m_baseUri = location + "/Scripts/python"
            self.m_scriptUriLocation = "document"
        else:
            self.m_baseUri = expandUri( self.s_UriMap[location] )
            self.m_scriptUriLocation = location
        log.debug( "initialized urihelper with baseUri="+self.m_baseUri + ",m_scriptUriLocation="+self.m_scriptUriLocation )

    def getRootStorageURI( self ):
        return self.m_baseUri

    def getStorageURI( self, scriptURI ):
        return self.scriptURI2StorageUri(scriptURI)

    def getScriptURI( self, storageURI ):
        return self.storageURI2ScriptUri(storageURI)

    def storageURI2ScriptUri( self, storageURI ):
        if not storageURI.startswith( self.m_baseUri ):
            message = "pythonscript: storage uri '" + storageURI + "' not in base uri '" + self.m_baseUri + "'"
            log.debug( message )
            raise RuntimeException( message )

        ret = "vnd.sun.star.script:" + \
              storageURI[len(self.m_baseUri)+1:].replace("/","|") + \
              "?language=" + LANGUAGENAME + "&location=" + self.m_scriptUriLocation
        log.debug( "converting storageURI="+storageURI + " to scriptURI=" + ret )
        return ret

    def scriptURI2StorageUri( self, scriptURI ):
        try:
            myUri = self.m_uriRefFac.parse(scriptURI)
            ret = self.m_baseUri + "/" + myUri.getName().replace( "|", "/" )
            log.debug( "converting scriptURI="+scriptURI + " to storageURI=" + ret )
            return ret
        except UnoException as e:
            log.error( "error during converting scriptURI="+scriptURI + ": " + e.Message)
            raise RuntimeException( "pythonscript:scriptURI2StorageUri: " +e.getMessage(), None )
        except Exception as e:
            log.error( "error during converting scriptURI="+scriptURI + ": " + str(e))
            raise RuntimeException( "pythonscript:scriptURI2StorageUri: " + str(e), None )


class ModuleEntry:
    def __init__( self, lastRead, module ):
        self.lastRead = lastRead
        self.module = module

def hasChanged( oldDate, newDate ):
    return newDate.Year > oldDate.Year or \
           newDate.Month > oldDate.Month or \
           newDate.Day > oldDate.Day or \
           newDate.Hours > oldDate.Hours or \
           newDate.Minutes > oldDate.Minutes or \
           newDate.Seconds > oldDate.Seconds or \
           newDate.HundredthSeconds > oldDate.HundredthSeconds

def ensureSourceState( code ):
    if not code.endswith( "\n" ):
        code = code + "\n"
    code = code.replace( "\r", "" )
    return code


def checkForPythonPathBesideScript( url ):
    if url.startswith( "file:" ):
        path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" );
        log.log( LogLevel.DEBUG,  "checking for existence of " + path )
        if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path:
            log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" )
            sys.path.append( path )

        path = unohelper.fileUrlToSystemPath( url+"/pythonpath" );
        log.log( LogLevel.DEBUG,  "checking for existence of " + path )
        if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path:
            log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" )
            sys.path.append( path )


class ScriptContext(unohelper.Base):
    def __init__( self, ctx, doc, inv ):
        self.ctx = ctx
        self.doc = doc
        self.inv = inv

   # XScriptContext
    def getDocument(self):
        if self.doc:
            return self.doc
        return self.getDesktop().getCurrentComponent()

    def getDesktop(self):
        return self.ctx.ServiceManager.createInstanceWithContext(
            "com.sun.star.frame.Desktop", self.ctx )

    def getComponentContext(self):
        return self.ctx

    def getInvocationContext(self):
        return self.inv

#----------------------------------
# Global Module Administration
# does not fit together with script
# engine lifetime management
#----------------------------------
#g_scriptContext = ScriptContext( uno.getComponentContext(), None )
#g_modules = {}
#def getModuleByUrl( url, sfa ):
#    entry =  g_modules.get(url)
#    load = True
#    lastRead = sfa.getDateTimeModified( url )
#    if entry:
#        if hasChanged( entry.lastRead, lastRead ):
#            log.debug("file " + url + " has changed, reloading")
#        else:
#            load = False
#
#    if load:
#        log.debug( "opening >" + url + "<" )
#
#        code = readTextFromStream( sfa.openFileRead( url ) )

        # execute the module
#        entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") )
#        entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext
#        entry.module.__file__ = url
#        exec code in entry.module.__dict__
#        g_modules[ url ] = entry
#        log.debug( "mapped " + url + " to " + str( entry.module ) )
#    return entry.module

class ProviderContext:
    def __init__( self, storageType, sfa, uriHelper, scriptContext ):
        self.storageType = storageType
        self.sfa = sfa
        self.uriHelper = uriHelper
        self.scriptContext = scriptContext
        self.modules = {}
        self.rootUrl = None
        self.mapPackageName2Path = None

    def getTransientPartFromUrl( self, url ):
        rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
        return rest[0:rest.find("/")]

    def getPackageNameFromUrl( self, url ):
        rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
        start = rest.find("/") +1
        return rest[start:rest.find("/",start)]


    def removePackageByUrl( self, url ):
        items = list(self.mapPackageName2Path.items())
        for i in items:
            if url in i[1].pathes:
                self.mapPackageName2Path.pop(i[0])
                break

    def addPackageByUrl( self, url ):
        packageName = self.getPackageNameFromUrl( url )
        transientPart = self.getTransientPartFromUrl( url )
        log.debug( "addPackageByUrl : " + packageName + ", " + transientPart + "("+url+")" + ", rootUrl="+self.rootUrl )
        if packageName in self.mapPackageName2Path:
            package = self.mapPackageName2Path[ packageName ]
            package.pathes = package.pathes + (url, )
        else:
            package = Package( (url,), transientPart)
            self.mapPackageName2Path[ packageName ] = package

    def isUrlInPackage( self, url ):
        values = list(self.mapPackageName2Path.values())
        for i in values:
#           print "checking " + url + " in " + str(i.pathes)
            if url in i.pathes:
                return True
#        print "false"
        return False

    def setPackageAttributes( self, mapPackageName2Path, rootUrl ):
        self.mapPackageName2Path = mapPackageName2Path
        self.rootUrl = rootUrl

    def getPersistentUrlFromStorageUrl( self, url ):
        # package name is the second directory
        ret = url
        if self.rootUrl:
            pos = len( self.rootUrl) +1
            ret = url[0:pos]+url[url.find("/",pos)+1:len(url)]
        log.debug( "getPersistentUrlFromStorageUrl " + url +  " -> "+ ret)
        return ret

    def getStorageUrlFromPersistentUrl( self, url):
        ret = url
        if self.rootUrl:
            pos = len(self.rootUrl)+1
            packageName = url[pos:url.find("/",pos+1)]
            package = self.mapPackageName2Path[ packageName ]
            ret = url[0:pos]+ package.transientPathElement + "/" + url[pos:len(url)]
        log.debug( "getStorageUrlFromPersistentUrl " + url + " -> "+ ret)
        return ret

    def getFuncsByUrl( self, url ):
        src = readTextFromStream( self.sfa.openFileRead( url ) )
        checkForPythonPathBesideScript( url[0:url.rfind('/')] )
        src = ensureSourceState( src )

        allFuncs = []
        g_exportedScripts = []

        a = ast.parse(src, url)

        if isinstance(a, ast.Module):
            for node in a.body:
                if isinstance(node, ast.FunctionDef):
                    allFuncs.append(node.name)
                elif isinstance(node, ast.Assign):
                    is_exported = False
                    for subnode in node.targets:
                        if isinstance(subnode, ast.Name) and \
                            subnode.id == "g_exportedScripts":
                            is_exported = True
                            break
                    if is_exported:
                        value_node = node.value
                        if isinstance(value_node, ast.List) or \
                            isinstance(value_node, ast.Tuple):
                            for elt in value_node.elts:
                                if isinstance(elt, ast.Str):
                                    g_exportedScripts.append(elt.s)
                                elif isinstance(elt, ast.Name):
                                    g_exportedScripts.append(elt.id)
                        elif isinstance(value_node, ast.Str):
                            g_exportedScripts.append(value_node.s)
                        elif isinstance(value_node, ast.Name):
                            g_exportedScripts.append(value_node.id)
                        return g_exportedScripts
        return allFuncs

    def getModuleByUrl( self, url ):
        entry =  self.modules.get(url)
        load = True
        lastRead = self.sfa.getDateTimeModified( url )
        if entry:
            if hasChanged( entry.lastRead, lastRead ):
                log.debug( "file " + url + " has changed, reloading" )
            else:
                load = False

        if load:
            log.debug( "opening >" + url + "<" )

            src = readTextFromStream( self.sfa.openFileRead( url ) )
            checkForPythonPathBesideScript( url[0:url.rfind('/')] )
            src = ensureSourceState( src )

            # execute the module
            entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") )
            entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.scriptContext

            code = None
            if url.startswith( "file:" ):
                code = compile( src, encfile(uno.fileUrlToSystemPath( url ) ), "exec" )
            else:
                code = compile( src, url, "exec" )
            exec(code, entry.module.__dict__)
            entry.module.__file__ = url
            self.modules[ url ] = entry
            log.debug( "mapped " + url + " to " + str( entry.module ) )
        return  entry.module

#--------------------------------------------------
def isScript( candidate ):
    ret = False
    if isinstance( candidate, type(isScript) ):
        ret = True
    return ret

#-------------------------------------------------------
class ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, XActionListener ):
    def __init__( self, provCtx, uri, fileName, funcName ):
        self.fileName = fileName
        self.funcName = funcName
        self.provCtx = provCtx
        self.uri = uri

    def getName( self ):
        return self.funcName

    def getChildNodes(self):
        return ()

    def hasChildNodes(self):
        return False

    def getType( self):
        return SCRIPT

    def getPropertyValue( self, name ):
        ret = None
        try:
            if name == "URI":
                ret = self.provCtx.uriHelper.getScriptURI(
                    self.provCtx.getPersistentUrlFromStorageUrl( self.uri + "$" + self.funcName ) )
            elif name == "Editable" and ENABLE_EDIT_DIALOG:
                ret = not self.provCtx.sfa.isReadOnly( self.uri )

            log.debug( "ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) )
        except Exception as e:
            log.error( "ScriptBrowseNode.getPropertyValue error " + lastException2String())
            raise

        return ret
    def setPropertyValue( self, name, value ):
        log.debug( "ScriptBrowseNode.setPropertyValue called " + name + "=" +str(value ) )
    def getPropertySetInfo( self ):
        log.debug( "ScriptBrowseNode.getPropertySetInfo called "  )
        return None

    def getIntrospection( self ):
        return None

    def invoke( self, name, params, outparamindex, outparams ):
        if name == "Editable":
            servicename = "com.sun.star.awt.DialogProvider"
            ctx = self.provCtx.scriptContext.getComponentContext()
            dlgprov = ctx.ServiceManager.createInstanceWithContext(
                servicename, ctx )

            self.editor = dlgprov.createDialog(
                "vnd.sun.star.script:" +
                "ScriptBindingLibrary.MacroEditor?location=application")

            code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri))
            code = ensureSourceState( code )
            self.editor.getControl("EditorTextField").setText(code)

            self.editor.getControl("RunButton").setActionCommand("Run")
            self.editor.getControl("RunButton").addActionListener(self)
            self.editor.getControl("SaveButton").setActionCommand("Save")
            self.editor.getControl("SaveButton").addActionListener(self)

            self.editor.execute()

        return None

    def actionPerformed( self, event ):
        try:
            if event.ActionCommand == "Run":
                code = self.editor.getControl("EditorTextField").getText()
                code = ensureSourceState( code )
                mod = imp.new_module("ooo_script_framework")
                mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext
                exec(code, mod.__dict__)
                values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
                if not values:
                    values = list(mod.__dict__.values())

                for i in values:
                    if isScript( i ):
                        i()
                        break

            elif event.ActionCommand == "Save":
                toWrite = uno.ByteSequence(
                    str(
                    self.editor.getControl("EditorTextField").getText().encode(
                    sys.getdefaultencoding())) )
                copyUrl = self.uri + ".orig"
                self.provCtx.sfa.move( self.uri, copyUrl )
                out = self.provCtx.sfa.openFileWrite( self.uri )
                out.writeBytes( toWrite )
                out.close()
                self.provCtx.sfa.kill( copyUrl )
#                log.debug("Save is not implemented yet")
#                text = self.editor.getControl("EditorTextField").getText()
#                log.debug("Would save: " + text)
        except Exception as e:
            # TODO: add an error box here !
            log.error( lastException2String() )


    def setValue( self, name, value ):
        return None

    def getValue( self, name ):
        return None

    def hasMethod( self, name ):
        return False

    def hasProperty( self, name ):
        return False


#-------------------------------------------------------
class FileBrowseNode( unohelper.Base, XBrowseNode ):
    def __init__( self, provCtx, uri , name ):
        self.provCtx = provCtx
        self.uri = uri
        self.name = name
        self.funcnames = None

    def getName( self ):
        return self.name

    def getChildNodes(self):
        ret = ()
        try:
            self.funcnames = self.provCtx.getFuncsByUrl( self.uri )

            scriptNodeList = []
            for i in self.funcnames:
                scriptNodeList.append(
                    ScriptBrowseNode(
                    self.provCtx, self.uri, self.name, i ))
            ret = tuple( scriptNodeList )
            log.debug( "returning " +str(len(ret)) + " ScriptChildNodes on " + self.uri )
        except Exception as e:
            text = lastException2String()
            log.error( "Error while evaluating " + self.uri + ":" + text )
            raise
        return ret

    def hasChildNodes(self):
        try:
            return len(self.getChildNodes()) > 0
        except Exception as e:
            return False

    def getType( self):
        return CONTAINER



class DirBrowseNode( unohelper.Base, XBrowseNode ):
    def __init__( self, provCtx, name, rootUrl ):
        self.provCtx = provCtx
        self.name = name
        self.rootUrl = rootUrl

    def getName( self ):
        return self.name

    def getChildNodes( self ):
        try:
            log.debug( "DirBrowseNode.getChildNodes called for " + self.rootUrl )
            contents = self.provCtx.sfa.getFolderContents( self.rootUrl, True )
            browseNodeList = []
            for i in contents:
                if i.endswith( ".py" ):
                    log.debug( "adding filenode " + i )
                    browseNodeList.append(
                        FileBrowseNode( self.provCtx, i, i[i.rfind("/")+1:len(i)-3] ) )
                elif self.provCtx.sfa.isFolder( i ) and not i.endswith("/pythonpath"):
                    log.debug( "adding DirBrowseNode " + i )
                    browseNodeList.append( DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)],i))
            return tuple( browseNodeList )
        except Exception as e:
            text = lastException2String()
            log.error( "DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl)
            log.error( text)
            return ()

    def hasChildNodes( self ):
        return True

    def getType( self ):
        return CONTAINER

    def getScript( self, uri ):
        log.debug( "DirBrowseNode getScript " + uri + " invoked" )
        raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 )


class ManifestHandler( XDocumentHandler, unohelper.Base ):
    def __init__( self, rootUrl ):
        self.rootUrl = rootUrl

    def startDocument( self ):
        self.urlList = []

    def endDocument( self ):
        pass

    def startElement( self , name, attlist):
        if name == "manifest:file-entry":
            if attlist.getValueByName( "manifest:media-type" ) == "application/vnd.sun.star.framework-script":
                self.urlList.append(
                    self.rootUrl + "/" + attlist.getValueByName( "manifest:full-path" ) )

    def endElement( self, name ):
        pass

    def characters ( self, chars ):
        pass

    def ignoreableWhitespace( self, chars ):
        pass

    def setDocumentLocator( self, locator ):
        pass

def isPyFileInPath( sfa, path ):
    ret = False
    contents = sfa.getFolderContents( path, True )
    for i in contents:
        if sfa.isFolder(i):
            ret = isPyFileInPath(sfa,i)
        else:
            if i.endswith(".py"):
                ret = True
        if ret:
            break
    return ret

# extracts META-INF directory from
def getPathesFromPackage( rootUrl, sfa ):
    ret = ()
    try:
        fileUrl = rootUrl + "/META-INF/manifest.xml"
        inputStream = sfa.openFileRead( fileUrl )
        parser = uno.getComponentContext().ServiceManager.createInstance( "com.sun.star.xml.sax.Parser" )
        handler = ManifestHandler( rootUrl )
        parser.setDocumentHandler( handler )
        parser.parseStream( InputSource( inputStream , "", fileUrl, fileUrl ) )
        for i in tuple(handler.urlList):
            if not isPyFileInPath( sfa, i ):
                handler.urlList.remove(i)
        ret = tuple( handler.urlList )
    except UnoException as e:
        text = lastException2String()
        log.debug( "getPathesFromPackage " + fileUrl + " Exception: " +text )
        pass
    return ret


class Package:
    def __init__( self, pathes, transientPathElement ):
        self.pathes = pathes
        self.transientPathElement = transientPathElement

class DummyInteractionHandler( unohelper.Base, XInteractionHandler ):
    def __init__( self ):
        pass
    def handle( self, event):
        log.debug( "pythonscript: DummyInteractionHandler.handle " + str( event ) )

class DummyProgressHandler( unohelper.Base, XProgressHandler ):
    def __init__( self ):
        pass

    def push( self,status ):
        log.debug( "pythonscript: DummyProgressHandler.push " + str( status ) )
    def update( self,status ):
        log.debug( "pythonscript: DummyProgressHandler.update " + str( status ) )
    def pop( self ):
        log.debug( "pythonscript: DummyProgressHandler.push " + str( event ) )

class CommandEnvironment(unohelper.Base, XCommandEnvironment):
    def __init__( self ):
        self.progressHandler = DummyProgressHandler()
        self.interactionHandler = DummyInteractionHandler()
    def getInteractionHandler( self ):
        return self.interactionHandler
    def getProgressHandler( self ):
        return self.progressHandler

#maybe useful for debugging purposes
#class ModifyListener( unohelper.Base, XModifyListener ):
#    def __init__( self ):
#        pass
#    def modified( self, event ):
#        log.debug( "pythonscript: ModifyListener.modified " + str( event ) )
#    def disposing( self, event ):
#        log.debug( "pythonscript: ModifyListener.disposing " + str( event ) )

def getModelFromDocUrl(ctx, url):
    """Get document model from document url."""
    doc = None
    args = ("Local", "Office")
    ucb = ctx.getServiceManager().createInstanceWithArgumentsAndContext(
        "com.sun.star.ucb.UniversalContentBroker", args, ctx)
    identifier = ucb.createContentIdentifier(url)
    content = ucb.queryContent(identifier)
    p = Property()
    p.Name = "DocumentModel"
    p.Handle = -1

    c = Command()
    c.Handle = -1
    c.Name = "getPropertyValues"
    c.Argument = uno.Any("[]com.sun.star.beans.Property", (p,))

    env = CommandEnvironment()
    try:
        ret = content.execute(c, 0, env)
        doc = ret.getObject(1, None)
    except Exception as e:
        log.isErrorLevel() and log.error("getModelFromDocUrl: %s" % url)
    return doc

def mapStorageType2PackageContext( storageType ):
    ret = storageType
    if( storageType == "share:uno_packages" ):
        ret = "shared"
    if( storageType == "user:uno_packages" ):
        ret = "user"
    return ret

def getPackageName2PathMap( sfa, storageType ):
    ret = {}
    packageManagerFactory = uno.getComponentContext().getValueByName(
        "/singletons/com.sun.star.deployment.thePackageManagerFactory" )
    packageManager = packageManagerFactory.getPackageManager(
        mapStorageType2PackageContext(storageType))
#    packageManager.addModifyListener( ModifyListener() )
    log.debug( "pythonscript: getPackageName2PathMap start getDeployedPackages" )
    packages = packageManager.getDeployedPackages(
        packageManager.createAbortChannel(), CommandEnvironment( ) )
    log.debug( "pythonscript: getPackageName2PathMap end getDeployedPackages (" + str(len(packages))+")" )

    for i in packages:
        log.debug( "inspecting package " + i.Name + "("+i.Identifier.Value+")" )
        transientPathElement = penultimateElement( i.URL )
        j = expandUri( i.URL )
        pathes = getPathesFromPackage( j, sfa )
        if len( pathes ) > 0:
            # map package name to url, we need this later
            log.isErrorLevel() and log.error( "adding Package " + transientPathElement + " " + str( pathes ) )
            ret[ lastElement( j ) ] = Package( pathes, transientPathElement )
    return ret

def penultimateElement( aStr ):
    lastSlash = aStr.rindex("/")
    penultimateSlash = aStr.rindex("/",0,lastSlash-1)
    return  aStr[ penultimateSlash+1:lastSlash ]

def lastElement( aStr):
    return aStr[ aStr.rfind( "/" )+1:len(aStr)]

class PackageBrowseNode( unohelper.Base, XBrowseNode ):
    def __init__( self, provCtx, name, rootUrl ):
        self.provCtx = provCtx
        self.name = name
        self.rootUrl = rootUrl

    def getName( self ):
        return self.name

    def getChildNodes( self ):
        items = list(self.provCtx.mapPackageName2Path.items())
        browseNodeList = []
        for i in items:
            if len( i[1].pathes ) == 1:
                browseNodeList.append(
                    DirBrowseNode( self.provCtx, i[0], i[1].pathes[0] ))
            else:
                for j in i[1].pathes:
                    browseNodeList.append(
                        DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j), j ) )
        return tuple( browseNodeList )

    def hasChildNodes( self ):
        return len( self.mapPackageName2Path ) > 0

    def getType( self ):
        return CONTAINER

    def getScript( self, uri ):
        log.debug( "DirBrowseNode getScript " + uri + " invoked" )
        raise IllegalArgumentException( "PackageBrowseNode couldn't instantiate script " + uri , self , 0 )




class PythonScript( unohelper.Base, XScript ):
    def __init__( self, func, mod ):
        self.func = func
        self.mod = mod
    def invoke(self, args, out, outindex ):
        log.debug( "PythonScript.invoke " + str( args ) )
        try:
            ret = self.func( *args )
        except UnoException as e:
            # UNO Exception continue to fly ...
            text = lastException2String()
            complete = "Error during invoking function " + \
                str(self.func.__name__) + " in module " + \
                self.mod.__file__ + " (" + text + ")"
            log.debug( complete )
            # some people may beat me up for modifying the exception text,
            # but otherwise office just shows
            # the type name and message text with no more information,
            # this is really bad for most users.
            e.Message = e.Message + " (" + complete + ")"
            raise
        except Exception as e:
            # General python exception are converted to uno RuntimeException
            text = lastException2String()
            complete = "Error during invoking function " + \
                str(self.func.__name__) + " in module " + \
                self.mod.__file__ + " (" + text + ")"
            log.debug( complete )
            raise RuntimeException( complete , self )
        log.debug( "PythonScript.invoke ret = " + str( ret ) )
        return ret, (), ()

def expandUri(  uri ):
    if uri.startswith( "vnd.sun.star.expand:" ):
        uri = uri.replace( "vnd.sun.star.expand:", "",1)
        uri = uno.getComponentContext().getByName(
                    "/singletons/com.sun.star.util.theMacroExpander" ).expandMacros( uri )
    if uri.startswith( "file:" ):
        uri = uno.absolutize("",uri)   # necessary to get rid of .. in uri
    return uri

#--------------------------------------------------------------
class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer):
    def __init__( self, ctx, *args ):
        if log.isDebugLevel():
            mystr = ""
            for i in args:
                if len(mystr) > 0:
                    mystr = mystr +","
                mystr = mystr + str(i)
            log.debug( "Entering PythonScriptProvider.ctor" + mystr )

        doc = None
        inv = None
        storageType = ""

        if isinstance(args[0],unicode ):
            storageType = args[0]
            if storageType.startswith( "vnd.sun.star.tdoc" ):
                doc = getModelFromDocUrl(ctx, storageType)
        else:
            inv = args[0]
            try:
                doc = inv.ScriptContainer
                content = ctx.getServiceManager().createInstanceWithContext(
                    "com.sun.star.frame.TransientDocumentsDocumentContentFactory",
                    ctx).createDocumentContent(doc)
                storageType = content.getIdentifier().getContentIdentifier()
            except Exception as e:
                text = lastException2String()
                log.error( text )

        isPackage = storageType.endswith( ":uno_packages" )

        try:
#            urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext(
#                "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx)
            urlHelper = MyUriHelper( ctx, storageType )
            log.debug( "got urlHelper " + str( urlHelper ) )

            rootUrl = expandUri( urlHelper.getRootStorageURI() )
            log.debug( storageType + " transformed to " + rootUrl )

            ucbService = "com.sun.star.ucb.SimpleFileAccess"
            sfa = ctx.ServiceManager.createInstanceWithContext( ucbService, ctx )
            if not sfa:
                log.debug("PythonScriptProvider couldn't instantiate " +ucbService)
                raise RuntimeException(
                    "PythonScriptProvider couldn't instantiate " +ucbService, self)
            self.provCtx = ProviderContext(
                storageType, sfa, urlHelper, ScriptContext( uno.getComponentContext(), doc, inv ) )
            if isPackage:
                mapPackageName2Path = getPackageName2PathMap( sfa, storageType )
                self.provCtx.setPackageAttributes( mapPackageName2Path , rootUrl )
                self.dirBrowseNode = PackageBrowseNode( self.provCtx, LANGUAGENAME, rootUrl )
            else:
                self.dirBrowseNode = DirBrowseNode( self.provCtx, LANGUAGENAME, rootUrl )

        except Exception as e:
            text = lastException2String()
            log.debug( "PythonScriptProvider could not be instantiated because of : " + text )
            raise e

    def getName( self ):
        return self.dirBrowseNode.getName()

    def getChildNodes( self ):
        return self.dirBrowseNode.getChildNodes()

    def hasChildNodes( self ):
        return self.dirBrowseNode.hasChildNodes()

    def getType( self ):
        return self.dirBrowseNode.getType()

    def getScript( self, uri ):
        log.debug( "DirBrowseNode getScript " + uri + " invoked" )

        raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 )

    def getScript( self, scriptUri ):
        try:
            log.debug( "getScript " + scriptUri + " invoked")

            storageUri = self.provCtx.getStorageUrlFromPersistentUrl(
                self.provCtx.uriHelper.getStorageURI(scriptUri) );
            log.debug( "getScript: storageUri = " + storageUri)
            fileUri = storageUri[0:storageUri.find( "$" )]
            funcName = storageUri[storageUri.find( "$" )+1:len(storageUri)]

            mod = self.provCtx.getModuleByUrl( fileUri )
            log.debug( " got mod " + str(mod) )

            func = mod.__dict__[ funcName ]

            log.debug( "got func " + str( func ) )
            return PythonScript( func, mod )
        except Exception as e:
            text = lastException2String()
            log.error( text )
            raise ScriptFrameworkErrorException( text, self, scriptUri, LANGUAGENAME, 0 )


    # XServiceInfo
    def getSupportedServices( self ):
        return g_ImplementationHelper.getSupportedServices(g_implName)

    def supportsService( self, ServiceName ):
        return g_ImplementationHelper.supportsService( g_implName, ServiceName )

    def getImplementationName(self):
        return g_implName

    def getByName( self, name ):
        log.debug( "getByName called" + str( name ))
        return None


    def getElementNames( self ):
        log.debug( "getElementNames called")
        return ()

    def hasByName( self, name ):
        try:
            log.debug( "hasByName called " + str( name ))
            uri = expandUri(name)
            ret = self.provCtx.isUrlInPackage( uri )
            log.debug( "hasByName " + uri + " " +str( ret ) )
            return ret
        except Exception as e:
            text = lastException2String()
            log.debug( "Error in hasByName:" +  text )
            return False

    def removeByName( self, name ):
        log.debug( "removeByName called" + str( name ))
        uri = expandUri( name )
        if self.provCtx.isUrlInPackage( uri ):
            self.provCtx.removePackageByUrl( uri )
        else:
            log.debug( "removeByName unknown uri " + str( name ) + ", ignoring" )
            raise NoSuchElementException( uri + "is not in package" , self )
        log.debug( "removeByName called" + str( uri ) + " successful" )

    def insertByName( self, name, value ):
        log.debug( "insertByName called " + str( name ) + " " + str( value ))
        uri = expandUri( name )
        if isPyFileInPath( self.provCtx.sfa, uri ):
            self.provCtx.addPackageByUrl( uri )
        else:
            # package is no python package ...
            log.debug( "insertByName: no python files in " + str( uri ) + ", ignoring" )
            raise IllegalArgumentException( uri + " does not contain .py files", self, 1 )
        log.debug( "insertByName called " + str( uri ) + " successful" )

    def replaceByName( self, name, value ):
        log.debug( "replaceByName called " + str( name ) + " " + str( value ))
        removeByName( name )
        insertByName( name )
        log.debug( "replaceByName called" + str( uri ) + " successful" )

    def getElementType( self ):
        log.debug( "getElementType called" )
        return uno.getTypeByName( "void" )

    def hasElements( self ):
        log.debug( "hasElements got called")
        return False

g_ImplementationHelper.addImplementation( \
        PythonScriptProvider,g_implName, \
    ("com.sun.star.script.provider.LanguageScriptProvider",
     "com.sun.star.script.provider.ScriptProviderFor"+ LANGUAGENAME,),)


log.debug( "pythonscript finished intializing" )
