"""
apipkg: control the exported namespace of a python package.

see http://pypi.python.org/pypi/apipkg

(c) holger krekel, 2009 - MIT license
"""
import os
import sys
from types import ModuleType

__version__ = '1.3.dev'

def _py_abspath(path):
    """
    special version of abspath
    that will leave paths from jython jars alone
    """
    if path.startswith('__pyclasspath__'):

        return path
    else:
        return os.path.abspath(path)

def initpkg(pkgname, exportdefs, attr=dict()):
    """ initialize given package from the export definitions. """
    oldmod = sys.modules.get(pkgname)
    d = {}
    f = getattr(oldmod, '__file__', None)
    if f:
        f = _py_abspath(f)
    d['__file__'] = f
    if hasattr(oldmod, '__version__'):
        d['__version__'] = oldmod.__version__
    if hasattr(oldmod, '__loader__'):
        d['__loader__'] = oldmod.__loader__
    if hasattr(oldmod, '__path__'):
        d['__path__'] = [_py_abspath(p) for p in oldmod.__path__]
    if '__doc__' not in exportdefs and getattr(oldmod, '__doc__', None):
        d['__doc__'] = oldmod.__doc__
    d.update(attr)
    if hasattr(oldmod, "__dict__"):
        oldmod.__dict__.update(d)
    mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
    sys.modules[pkgname] = mod

def importobj(modpath, attrname):
    module = __import__(modpath, None, None, ['__doc__'])
    if not attrname:
        return module

    retval = module
    names = attrname.split(".")
    for x in names:
        retval = getattr(retval, x)
    return retval

class ApiModule(ModuleType):
    def __docget(self):
        try:
            return self.__doc
        except AttributeError:
            if '__doc__' in self.__map__:
                return self.__makeattr('__doc__')
    def __docset(self, value):
        self.__doc = value
    __doc__ = property(__docget, __docset)

    def __init__(self, name, importspec, implprefix=None, attr=None):
        self.__name__ = name
        self.__all__ = [x for x in importspec if x != '__onfirstaccess__']
        self.__map__ = {}
        self.__implprefix__ = implprefix or name
        if attr:
            for name, val in attr.items():
                # print "setting", self.__name__, name, val
                setattr(self, name, val)
        for name, importspec in importspec.items():
            if isinstance(importspec, dict):
                subname = '%s.%s' % (self.__name__, name)
                apimod = ApiModule(subname, importspec, implprefix)
                sys.modules[subname] = apimod
                setattr(self, name, apimod)
            else:
                parts = importspec.split(':')
                modpath = parts.pop(0)
                attrname = parts and parts[0] or ""
                if modpath[0] == '.':
                    modpath = implprefix + modpath

                if not attrname:
                    subname = '%s.%s' % (self.__name__, name)
                    apimod = AliasModule(subname, modpath)
                    sys.modules[subname] = apimod
                    if '.' not in name:
                        setattr(self, name, apimod)
                else:
                    self.__map__[name] = (modpath, attrname)

    def __repr__(self):
        l = []
        if hasattr(self, '__version__'):
            l.append("version=" + repr(self.__version__))
        if hasattr(self, '__file__'):
            l.append('from ' + repr(self.__file__))
        if l:
            return '<ApiModule %r %s>' % (self.__name__, " ".join(l))
        return '<ApiModule %r>' % (self.__name__,)

    def __makeattr(self, name):
        """lazily compute value for name or raise AttributeError if unknown."""
        # print "makeattr", self.__name__, name
        target = None
        if '__onfirstaccess__' in self.__map__:
            target = self.__map__.pop('__onfirstaccess__')
            importobj(*target)()
        try:
            modpath, attrname = self.__map__[name]
        except KeyError:
            if target is not None and name != '__onfirstaccess__':
                # retry, onfirstaccess might have set attrs
                return getattr(self, name)
            raise AttributeError(name)
        else:
            result = importobj(modpath, attrname)
            setattr(self, name, result)
            try:
                del self.__map__[name]
            except KeyError:
                pass  # in a recursive-import situation a double-del can happen
            return result

    __getattr__ = __makeattr

    def __dict__(self):
        # force all the content of the module to be loaded when __dict__ is read
        dictdescr = ModuleType.__dict__['__dict__']
        dict = dictdescr.__get__(self)
        if dict is not None:
            hasattr(self, 'some')
            for name in self.__all__:
                try:
                    self.__makeattr(name)
                except AttributeError:
                    pass
        return dict
    __dict__ = property(__dict__)


def AliasModule(modname, modpath, attrname=None):
    mod = []

    def getmod():
        if not mod:
            x = importobj(modpath, None)
            if attrname is not None:
                x = getattr(x, attrname)
            mod.append(x)
        return mod[0]

    class AliasModule(ModuleType):

        def __repr__(self):
            x = modpath
            if attrname:
                x += "." + attrname
            return '<AliasModule %r for %r>' % (modname, x)

        def __getattribute__(self, name):
            try:
                return getattr(getmod(), name)
            except ImportError:
                return None

        def __setattr__(self, name, value):
            setattr(getmod(), name, value)

        def __delattr__(self, name):
            delattr(getmod(), name)

    return AliasModule(str(modname))
