# mako/template.py
# Copyright 2006-2019 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."""

import json
import os
import re
import shutil
import stat
import sys
import tempfile
import types
import weakref

from mako import cache
from mako import codegen
from mako import compat
from mako import exceptions
from mako import runtime
from mako import util
from mako.lexer import Lexer


class Template(object):

    r"""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.

     .. seealso::

        :paramref:`.Template.include_error_handler` - include-specific
        error handler function

    :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 include_error_handler: An error handler that runs when this template
     is included within another one via the ``<%include>`` tag, and raises an
     error.  Compare to the :paramref:`.Template.error_handler` option.

     .. versionadded:: 1.0.6

     .. seealso::

        :paramref:`.Template.error_handler` - top-level error handler function

    :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,
        include_error_handler=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, uri)
        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.include_error_handler = include_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, 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, 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 list_defs(self):
        """return a list of defs in the template.

        .. versionadded:: 1.0.4

        """
        return [i[7:] for i in dir(self.module) if i[:7] == "render_"]

    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,
        include_error_handler=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,
            module._template_uri,
        )

        self.callable_ = self.module.render_body
        self.format_exceptions = format_exceptions
        self.error_handler = error_handler
        self.include_error_handler = include_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.include_error_handler = parent.include_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,
        template_uri,
    ):
        self.module = module
        self.module_filename = module_filename
        self.template_filename = template_filename
        self.module_source = module_source
        self.template_source = template_source
        self.template_uri = template_uri
        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 = 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:
            f_line_map = source_map["full_line_map"] = []
            line_map = source_map["line_map"]

            curr_templ_line = 1
            for mod_line in range(1, max(line_map)):
                if mod_line in line_map:
                    curr_templ_line = line_map[mod_line]
                f_line_map.append(curr_templ_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]
