# mako/template.py
# Copyright (C) 2006-2014 the Mako authors and contributors <see AUTHORS file>
#
# This module is part of Mako and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

"""Provides the Template class, a facade for parsing, generating and executing
template strings, as well as template runtime operations."""

from mako.lexer import Lexer
from mako import runtime, util, exceptions, codegen, cache, compat
import os
import re
import shutil
import stat
import sys
import tempfile
import types
import weakref


class Template(object):
    """Represents a compiled template.

    :class:`.Template` includes a reference to the original
    template source (via the :attr:`.source` attribute)
    as well as the source code of the
    generated Python module (i.e. the :attr:`.code` attribute),
    as well as a reference to an actual Python module.

    :class:`.Template` is constructed using either a literal string
    representing the template text, or a filename representing a filesystem
    path to a source file.

    :param text: textual template source.  This argument is mutually
     exclusive versus the ``filename`` parameter.

    :param filename: filename of the source template.  This argument is
     mutually exclusive versus the ``text`` parameter.

    :param buffer_filters: string list of filters to be applied
     to the output of ``%def``\ s which are buffered, cached, or otherwise
     filtered, after all filters
     defined with the ``%def`` itself have been applied. Allows the
     creation of default expression filters that let the output
     of return-valued ``%def``\ s "opt out" of that filtering via
     passing special attributes or objects.

    :param bytestring_passthrough: When ``True``, and ``output_encoding`` is
     set to ``None``, and :meth:`.Template.render` is used to render,
     the `StringIO` or `cStringIO` buffer will be used instead of the
     default "fast" buffer.   This allows raw bytestrings in the
     output stream, such as in expressions, to pass straight
     through to the buffer.  This flag is forced
     to ``True`` if ``disable_unicode`` is also configured.

     .. versionadded:: 0.4
        Added to provide the same behavior as that of the previous series.

    :param cache_args: Dictionary of cache configuration arguments that
     will be passed to the :class:`.CacheImpl`.   See :ref:`caching_toplevel`.

    :param cache_dir:

     .. deprecated:: 0.6
        Use the ``'dir'`` argument in the ``cache_args`` dictionary.
        See :ref:`caching_toplevel`.

    :param cache_enabled: Boolean flag which enables caching of this
     template.  See :ref:`caching_toplevel`.

    :param cache_impl: String name of a :class:`.CacheImpl` caching
     implementation to use.   Defaults to ``'beaker'``.

    :param cache_type:

     .. deprecated:: 0.6
        Use the ``'type'`` argument in the ``cache_args`` dictionary.
        See :ref:`caching_toplevel`.

    :param cache_url:

     .. deprecated:: 0.6
        Use the ``'url'`` argument in the ``cache_args`` dictionary.
        See :ref:`caching_toplevel`.

    :param default_filters: List of string filter names that will
     be applied to all expressions.  See :ref:`filtering_default_filters`.

    :param disable_unicode: Disables all awareness of Python Unicode
     objects.  See :ref:`unicode_disabled`.

    :param enable_loop: When ``True``, enable the ``loop`` context variable.
     This can be set to ``False`` to support templates that may
     be making usage of the name "``loop``".   Individual templates can
     re-enable the "loop" context by placing the directive
     ``enable_loop="True"`` inside the ``<%page>`` tag -- see
     :ref:`migrating_loop`.

    :param encoding_errors: Error parameter passed to ``encode()`` when
     string encoding is performed. See :ref:`usage_unicode`.

    :param error_handler: Python callable which is called whenever
     compile or runtime exceptions occur. The callable is passed
     the current context as well as the exception. If the
     callable returns ``True``, the exception is considered to
     be handled, else it is re-raised after the function
     completes. Is used to provide custom error-rendering
     functions.

    :param format_exceptions: if ``True``, exceptions which occur during
     the render phase of this template will be caught and
     formatted into an HTML error page, which then becomes the
     rendered result of the :meth:`.render` call. Otherwise,
     runtime exceptions are propagated outwards.

    :param imports: String list of Python statements, typically individual
     "import" lines, which will be placed into the module level
     preamble of all generated Python modules. See the example
     in :ref:`filtering_default_filters`.

    :param future_imports: String list of names to import from `__future__`.
     These will be concatenated into a comma-separated string and inserted
     into the beginning of the template, e.g. ``futures_imports=['FOO',
     'BAR']`` results in ``from __future__ import FOO, BAR``.  If you're
     interested in using features like the new division operator, you must
     use future_imports to convey that to the renderer, as otherwise the
     import will not appear as the first executed statement in the generated
     code and will therefore not have the desired effect.

    :param input_encoding: Encoding of the template's source code.  Can
     be used in lieu of the coding comment. See
     :ref:`usage_unicode` as well as :ref:`unicode_toplevel` for
     details on source encoding.

    :param lookup: a :class:`.TemplateLookup` instance that will be used
     for all file lookups via the ``<%namespace>``,
     ``<%include>``, and ``<%inherit>`` tags. See
     :ref:`usage_templatelookup`.

    :param module_directory: Filesystem location where generated
     Python module files will be placed.

    :param module_filename: Overrides the filename of the generated
     Python module file. For advanced usage only.

    :param module_writer: A callable which overrides how the Python
     module is written entirely.  The callable is passed the
     encoded source content of the module and the destination
     path to be written to.   The default behavior of module writing
     uses a tempfile in conjunction with a file move in order
     to make the operation atomic.   So a user-defined module
     writing function that mimics the default behavior would be:

     .. sourcecode:: python

         import tempfile
         import os
         import shutil

         def module_writer(source, outputpath):
             (dest, name) = \\
                 tempfile.mkstemp(
                     dir=os.path.dirname(outputpath)
                 )

             os.write(dest, source)
             os.close(dest)
             shutil.move(name, outputpath)

         from mako.template import Template
         mytemplate = Template(
                         filename="index.html",
                         module_directory="/path/to/modules",
                         module_writer=module_writer
                     )

     The function is provided for unusual configurations where
     certain platform-specific permissions or other special
     steps are needed.

    :param output_encoding: The encoding to use when :meth:`.render`
     is called.
     See :ref:`usage_unicode` as well as :ref:`unicode_toplevel`.

    :param preprocessor: Python callable which will be passed
     the full template source before it is parsed. The return
     result of the callable will be used as the template source
     code.

    :param lexer_cls: A :class:`.Lexer` class used to parse
     the template.   The :class:`.Lexer` class is used by
     default.

     .. versionadded:: 0.7.4

    :param strict_undefined: Replaces the automatic usage of
     ``UNDEFINED`` for any undeclared variables not located in
     the :class:`.Context` with an immediate raise of
     ``NameError``. The advantage is immediate reporting of
     missing variables which include the name.

     .. versionadded:: 0.3.6

    :param uri: string URI or other identifier for this template.
     If not provided, the ``uri`` is generated from the filesystem
     path, or from the in-memory identity of a non-file-based
     template. The primary usage of the ``uri`` is to provide a key
     within :class:`.TemplateLookup`, as well as to generate the
     file path of the generated Python module file, if
     ``module_directory`` is specified.

    """

    lexer_cls = Lexer

    def __init__(self,
                    text=None,
                    filename=None,
                    uri=None,
                    format_exceptions=False,
                    error_handler=None,
                    lookup=None,
                    output_encoding=None,
                    encoding_errors='strict',
                    module_directory=None,
                    cache_args=None,
                    cache_impl='beaker',
                    cache_enabled=True,
                    cache_type=None,
                    cache_dir=None,
                    cache_url=None,
                    module_filename=None,
                    input_encoding=None,
                    disable_unicode=False,
                    module_writer=None,
                    bytestring_passthrough=False,
                    default_filters=None,
                    buffer_filters=(),
                    strict_undefined=False,
                    imports=None,
                    future_imports=None,
                    enable_loop=True,
                    preprocessor=None,
                    lexer_cls=None):
        if uri:
            self.module_id = re.sub(r'\W', "_", uri)
            self.uri = uri
        elif filename:
            self.module_id = re.sub(r'\W', "_", filename)
            drive, path = os.path.splitdrive(filename)
            path = os.path.normpath(path).replace(os.path.sep, "/")
            self.uri = path
        else:
            self.module_id = "memory:" + hex(id(self))
            self.uri = self.module_id

        u_norm = self.uri
        if u_norm.startswith("/"):
            u_norm = u_norm[1:]
        u_norm = os.path.normpath(u_norm)
        if u_norm.startswith(".."):
            raise exceptions.TemplateLookupException(
                    "Template uri \"%s\" is invalid - "
                    "it cannot be relative outside "
                    "of the root path." % self.uri)

        self.input_encoding = input_encoding
        self.output_encoding = output_encoding
        self.encoding_errors = encoding_errors
        self.disable_unicode = disable_unicode
        self.bytestring_passthrough = bytestring_passthrough or disable_unicode
        self.enable_loop = enable_loop
        self.strict_undefined = strict_undefined
        self.module_writer = module_writer

        if compat.py3k and disable_unicode:
            raise exceptions.UnsupportedError(
                                    "Mako for Python 3 does not "
                                    "support disabling Unicode")
        elif output_encoding and disable_unicode:
            raise exceptions.UnsupportedError(
                                    "output_encoding must be set to "
                                    "None when disable_unicode is used.")
        if default_filters is None:
            if compat.py3k or self.disable_unicode:
                self.default_filters = ['str']
            else:
                self.default_filters = ['unicode']
        else:
            self.default_filters = default_filters
        self.buffer_filters = buffer_filters

        self.imports = imports
        self.future_imports = future_imports
        self.preprocessor = preprocessor

        if lexer_cls is not None:
            self.lexer_cls = lexer_cls

        # if plain text, compile code in memory only
        if text is not None:
            (code, module) = _compile_text(self, text, filename)
            self._code = code
            self._source = text
            ModuleInfo(module, None, self, filename, code, text)
        elif filename is not None:
            # if template filename and a module directory, load
            # a filesystem-based module file, generating if needed
            if module_filename is not None:
                path = module_filename
            elif module_directory is not None:
                path = os.path.abspath(
                        os.path.join(
                            os.path.normpath(module_directory),
                            u_norm + ".py"
                            )
                        )
            else:
                path = None
            module = self._compile_from_file(path, filename)
        else:
            raise exceptions.RuntimeException(
                                "Template requires text or filename")

        self.module = module
        self.filename = filename
        self.callable_ = self.module.render_body
        self.format_exceptions = format_exceptions
        self.error_handler = error_handler
        self.lookup = lookup

        self.module_directory = module_directory

        self._setup_cache_args(
            cache_impl, cache_enabled, cache_args,
            cache_type, cache_dir, cache_url
        )


    @util.memoized_property
    def reserved_names(self):
        if self.enable_loop:
            return codegen.RESERVED_NAMES
        else:
            return codegen.RESERVED_NAMES.difference(['loop'])

    def _setup_cache_args(self,
                cache_impl, cache_enabled, cache_args,
                cache_type, cache_dir, cache_url):
        self.cache_impl = cache_impl
        self.cache_enabled = cache_enabled
        if cache_args:
            self.cache_args = cache_args
        else:
            self.cache_args = {}

        # transfer deprecated cache_* args
        if cache_type:
            self.cache_args['type'] = cache_type
        if cache_dir:
            self.cache_args['dir'] = cache_dir
        if cache_url:
            self.cache_args['url'] = cache_url

    def _compile_from_file(self, path, filename):
        if path is not None:
            util.verify_directory(os.path.dirname(path))
            filemtime = os.stat(filename)[stat.ST_MTIME]
            if not os.path.exists(path) or \
                        os.stat(path)[stat.ST_MTIME] < filemtime:
                data = util.read_file(filename)
                _compile_module_file(
                            self,
                            data,
                            filename,
                            path,
                            self.module_writer)
            module = compat.load_module(self.module_id, path)
            del sys.modules[self.module_id]
            if module._magic_number != codegen.MAGIC_NUMBER:
                data = util.read_file(filename)
                _compile_module_file(
                            self,
                            data,
                            filename,
                            path,
                            self.module_writer)
                module = compat.load_module(self.module_id, path)
                del sys.modules[self.module_id]
            ModuleInfo(module, path, self, filename, None, None)
        else:
            # template filename and no module directory, compile code
            # in memory
            data = util.read_file(filename)
            code, module = _compile_text(
                                self,
                                data,
                                filename)
            self._source = None
            self._code = code
            ModuleInfo(module, None, self, filename, code, None)
        return module

    @property
    def source(self):
        """Return the template source code for this :class:`.Template`."""

        return _get_module_info_from_callable(self.callable_).source

    @property
    def code(self):
        """Return the module source code for this :class:`.Template`."""

        return _get_module_info_from_callable(self.callable_).code

    @util.memoized_property
    def cache(self):
        return cache.Cache(self)

    @property
    def cache_dir(self):
        return self.cache_args['dir']
    @property
    def cache_url(self):
        return self.cache_args['url']
    @property
    def cache_type(self):
        return self.cache_args['type']

    def render(self, *args, **data):
        """Render the output of this template as a string.

        If the template specifies an output encoding, the string
        will be encoded accordingly, else the output is raw (raw
        output uses `cStringIO` and can't handle multibyte
        characters). A :class:`.Context` object is created corresponding
        to the given data. Arguments that are explicitly declared
        by this template's internal rendering method are also
        pulled from the given ``*args``, ``**data`` members.

        """
        return runtime._render(self, self.callable_, args, data)

    def render_unicode(self, *args, **data):
        """Render the output of this template as a unicode object."""

        return runtime._render(self,
                                self.callable_,
                                args,
                                data,
                                as_unicode=True)

    def render_context(self, context, *args, **kwargs):
        """Render this :class:`.Template` with the given context.

        The data is written to the context's buffer.

        """
        if getattr(context, '_with_template', None) is None:
            context._set_with_template(self)
        runtime._render_context(self,
                                self.callable_,
                                context,
                                *args,
                                **kwargs)

    def has_def(self, name):
        return hasattr(self.module, "render_%s" % name)

    def get_def(self, name):
        """Return a def of this template as a :class:`.DefTemplate`."""

        return DefTemplate(self, getattr(self.module, "render_%s" % name))

    def _get_def_callable(self, name):
        return getattr(self.module, "render_%s" % name)

    @property
    def last_modified(self):
        return self.module._modified_time

class ModuleTemplate(Template):
    """A Template which is constructed given an existing Python module.

        e.g.::

        t = Template("this is a template")
        f = file("mymodule.py", "w")
        f.write(t.code)
        f.close()

        import mymodule

        t = ModuleTemplate(mymodule)
        print t.render()

    """

    def __init__(self, module,
                        module_filename=None,
                        template=None,
                        template_filename=None,
                        module_source=None,
                        template_source=None,
                        output_encoding=None,
                        encoding_errors='strict',
                        disable_unicode=False,
                        bytestring_passthrough=False,
                        format_exceptions=False,
                        error_handler=None,
                        lookup=None,
                        cache_args=None,
                        cache_impl='beaker',
                        cache_enabled=True,
                        cache_type=None,
                        cache_dir=None,
                        cache_url=None,
    ):
        self.module_id = re.sub(r'\W', "_", module._template_uri)
        self.uri = module._template_uri
        self.input_encoding = module._source_encoding
        self.output_encoding = output_encoding
        self.encoding_errors = encoding_errors
        self.disable_unicode = disable_unicode
        self.bytestring_passthrough = bytestring_passthrough or disable_unicode
        self.enable_loop = module._enable_loop

        if compat.py3k and disable_unicode:
            raise exceptions.UnsupportedError(
                                    "Mako for Python 3 does not "
                                    "support disabling Unicode")
        elif output_encoding and disable_unicode:
            raise exceptions.UnsupportedError(
                                    "output_encoding must be set to "
                                    "None when disable_unicode is used.")

        self.module = module
        self.filename = template_filename
        ModuleInfo(module,
                        module_filename,
                        self,
                        template_filename,
                        module_source,
                        template_source)

        self.callable_ = self.module.render_body
        self.format_exceptions = format_exceptions
        self.error_handler = error_handler
        self.lookup = lookup
        self._setup_cache_args(
            cache_impl, cache_enabled, cache_args,
            cache_type, cache_dir, cache_url
        )

class DefTemplate(Template):
    """A :class:`.Template` which represents a callable def in a parent
    template."""

    def __init__(self, parent, callable_):
        self.parent = parent
        self.callable_ = callable_
        self.output_encoding = parent.output_encoding
        self.module = parent.module
        self.encoding_errors = parent.encoding_errors
        self.format_exceptions = parent.format_exceptions
        self.error_handler = parent.error_handler
        self.enable_loop = parent.enable_loop
        self.lookup = parent.lookup
        self.bytestring_passthrough = parent.bytestring_passthrough

    def get_def(self, name):
        return self.parent.get_def(name)

class ModuleInfo(object):
    """Stores information about a module currently loaded into
    memory, provides reverse lookups of template source, module
    source code based on a module's identifier.

     """
    _modules = weakref.WeakValueDictionary()

    def __init__(self,
                    module,
                    module_filename,
                    template,
                    template_filename,
                    module_source,
                    template_source):
        self.module = module
        self.module_filename = module_filename
        self.template_filename = template_filename
        self.module_source = module_source
        self.template_source = template_source
        self._modules[module.__name__] = template._mmarker = self
        if module_filename:
            self._modules[module_filename] = self

    @classmethod
    def get_module_source_metadata(cls, module_source, full_line_map=False):
        source_map = re.search(
                        r"__M_BEGIN_METADATA(.+?)__M_END_METADATA",
                        module_source, re.S).group(1)
        source_map = compat.json.loads(source_map)
        source_map['line_map'] = dict((int(k), int(v))
                                    for k, v in source_map['line_map'].items())
        if full_line_map:
            line_map = source_map['full_line_map'] = dict(
                (k, v) for k, v in source_map['line_map'].items()
            )

            for mod_line in reversed(sorted(line_map)):
                tmpl_line = line_map[mod_line]
                while mod_line > 0:
                    mod_line -= 1
                    if mod_line in line_map:
                        break
                    line_map[mod_line] = tmpl_line
        return source_map

    @property
    def code(self):
        if self.module_source is not None:
            return self.module_source
        else:
            return util.read_python_file(self.module_filename)

    @property
    def source(self):
        if self.template_source is not None:
            if self.module._source_encoding and \
                    not isinstance(self.template_source, compat.text_type):
                return self.template_source.decode(
                                self.module._source_encoding)
            else:
                return self.template_source
        else:
            data = util.read_file(self.template_filename)
            if self.module._source_encoding:
                return data.decode(self.module._source_encoding)
            else:
                return data

def _compile(template, text, filename, generate_magic_comment):
    lexer = template.lexer_cls(text,
                           filename,
                           disable_unicode=template.disable_unicode,
                           input_encoding=template.input_encoding,
                           preprocessor=template.preprocessor)
    node = lexer.parse()
    source = codegen.compile(node,
                            template.uri,
                            filename,
                            default_filters=template.default_filters,
                            buffer_filters=template.buffer_filters,
                            imports=template.imports,
                            future_imports=template.future_imports,
                            source_encoding=lexer.encoding,
                            generate_magic_comment=generate_magic_comment,
                            disable_unicode=template.disable_unicode,
                            strict_undefined=template.strict_undefined,
                            enable_loop=template.enable_loop,
                            reserved_names=template.reserved_names)
    return source, lexer

def _compile_text(template, text, filename):
    identifier = template.module_id
    source, lexer = _compile(template, text, filename,
                        generate_magic_comment=template.disable_unicode)

    cid = identifier
    if not compat.py3k and isinstance(cid, compat.text_type):
        cid = cid.encode()
    module = types.ModuleType(cid)
    code = compile(source, cid, 'exec')

    # this exec() works for 2.4->3.3.
    exec(code, module.__dict__, module.__dict__)
    return (source, module)

def _compile_module_file(template, text, filename, outputpath, module_writer):
    source, lexer = _compile(template, text, filename,
                        generate_magic_comment=True)

    if isinstance(source, compat.text_type):
        source = source.encode(lexer.encoding or 'ascii')

    if module_writer:
        module_writer(source, outputpath)
    else:
        # make tempfiles in the same location as the ultimate
        # location.   this ensures they're on the same filesystem,
        # avoiding synchronization issues.
        (dest, name) = tempfile.mkstemp(dir=os.path.dirname(outputpath))

        os.write(dest, source)
        os.close(dest)
        shutil.move(name, outputpath)

def _get_module_info_from_callable(callable_):
    if compat.py3k:
        return _get_module_info(callable_.__globals__['__name__'])
    else:
        return _get_module_info(callable_.func_globals['__name__'])

def _get_module_info(filename):
    return ModuleInfo._modules[filename]

