# mako/parsetree.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

"""defines the parse tree components for Mako templates."""

from mako import exceptions, ast, util, filters, compat
import re

class Node(object):
    """base class for a Node in the parse tree."""

    def __init__(self, source, lineno, pos, filename):
        self.source = source
        self.lineno = lineno
        self.pos = pos
        self.filename = filename

    @property
    def exception_kwargs(self):
        return {'source': self.source, 'lineno': self.lineno,
                'pos': self.pos, 'filename': self.filename}

    def get_children(self):
        return []

    def accept_visitor(self, visitor):
        def traverse(node):
            for n in node.get_children():
                n.accept_visitor(visitor)

        method = getattr(visitor, "visit" + self.__class__.__name__, traverse)
        method(self)

class TemplateNode(Node):
    """a 'container' node that stores the overall collection of nodes."""

    def __init__(self, filename):
        super(TemplateNode, self).__init__('', 0, 0, filename)
        self.nodes = []
        self.page_attributes = {}

    def get_children(self):
        return self.nodes

    def __repr__(self):
        return "TemplateNode(%s, %r)" % (
                    util.sorted_dict_repr(self.page_attributes),
                    self.nodes)

class ControlLine(Node):
    """defines a control line, a line-oriented python line or end tag.

    e.g.::

        % if foo:
            (markup)
        % endif

    """

    has_loop_context = False

    def __init__(self, keyword, isend, text, **kwargs):
        super(ControlLine, self).__init__(**kwargs)
        self.text = text
        self.keyword = keyword
        self.isend = isend
        self.is_primary = keyword in ['for', 'if', 'while', 'try', 'with']
        self.nodes = []
        if self.isend:
            self._declared_identifiers = []
            self._undeclared_identifiers = []
        else:
            code = ast.PythonFragment(text, **self.exception_kwargs)
            self._declared_identifiers = code.declared_identifiers
            self._undeclared_identifiers = code.undeclared_identifiers

    def get_children(self):
        return self.nodes

    def declared_identifiers(self):
        return self._declared_identifiers

    def undeclared_identifiers(self):
        return self._undeclared_identifiers

    def is_ternary(self, keyword):
        """return true if the given keyword is a ternary keyword
        for this ControlLine"""

        return keyword in {
            'if':set(['else', 'elif']),
            'try':set(['except', 'finally']),
            'for':set(['else'])
        }.get(self.keyword, [])

    def __repr__(self):
        return "ControlLine(%r, %r, %r, %r)" % (
            self.keyword,
            self.text,
            self.isend,
            (self.lineno, self.pos)
        )

class Text(Node):
    """defines plain text in the template."""

    def __init__(self, content, **kwargs):
        super(Text, self).__init__(**kwargs)
        self.content = content

    def __repr__(self):
        return "Text(%r, %r)" % (self.content, (self.lineno, self.pos))

class Code(Node):
    """defines a Python code block, either inline or module level.

    e.g.::

        inline:
        <%
            x = 12
        %>

        module level:
        <%!
            import logger
        %>

    """

    def __init__(self, text, ismodule, **kwargs):
        super(Code, self).__init__(**kwargs)
        self.text = text
        self.ismodule = ismodule
        self.code = ast.PythonCode(text, **self.exception_kwargs)

    def declared_identifiers(self):
        return self.code.declared_identifiers

    def undeclared_identifiers(self):
        return self.code.undeclared_identifiers

    def __repr__(self):
        return "Code(%r, %r, %r)" % (
            self.text,
            self.ismodule,
            (self.lineno, self.pos)
        )

class Comment(Node):
    """defines a comment line.

    # this is a comment

    """

    def __init__(self, text, **kwargs):
        super(Comment, self).__init__(**kwargs)
        self.text = text

    def __repr__(self):
        return "Comment(%r, %r)" % (self.text, (self.lineno, self.pos))

class Expression(Node):
    """defines an inline expression.

    ${x+y}

    """

    def __init__(self, text, escapes, **kwargs):
        super(Expression, self).__init__(**kwargs)
        self.text = text
        self.escapes = escapes
        self.escapes_code = ast.ArgumentList(escapes, **self.exception_kwargs)
        self.code = ast.PythonCode(text, **self.exception_kwargs)

    def declared_identifiers(self):
        return []

    def undeclared_identifiers(self):
        # TODO: make the "filter" shortcut list configurable at parse/gen time
        return self.code.undeclared_identifiers.union(
                self.escapes_code.undeclared_identifiers.difference(
                    set(filters.DEFAULT_ESCAPES.keys())
                )
            ).difference(self.code.declared_identifiers)

    def __repr__(self):
        return "Expression(%r, %r, %r)" % (
            self.text,
            self.escapes_code.args,
            (self.lineno, self.pos)
        )

class _TagMeta(type):
    """metaclass to allow Tag to produce a subclass according to
    its keyword"""

    _classmap = {}

    def __init__(cls, clsname, bases, dict):
        if getattr(cls, '__keyword__', None) is not None:
            cls._classmap[cls.__keyword__] = cls
        super(_TagMeta, cls).__init__(clsname, bases, dict)

    def __call__(cls, keyword, attributes, **kwargs):
        if ":" in keyword:
            ns, defname = keyword.split(':')
            return type.__call__(CallNamespaceTag, ns, defname,
                                        attributes, **kwargs)

        try:
            cls = _TagMeta._classmap[keyword]
        except KeyError:
            raise exceptions.CompileException(
                "No such tag: '%s'" % keyword,
                source=kwargs['source'],
                lineno=kwargs['lineno'],
                pos=kwargs['pos'],
                filename=kwargs['filename']
            )
        return type.__call__(cls, keyword, attributes, **kwargs)

class Tag(compat.with_metaclass(_TagMeta, Node)):
    """abstract base class for tags.

    <%sometag/>

    <%someothertag>
        stuff
    </%someothertag>

    """
    __keyword__ = None

    def __init__(self, keyword, attributes, expressions,
                        nonexpressions, required, **kwargs):
        """construct a new Tag instance.

        this constructor not called directly, and is only called
        by subclasses.

        :param keyword: the tag keyword

        :param attributes: raw dictionary of attribute key/value pairs

        :param expressions: a set of identifiers that are legal attributes,
         which can also contain embedded expressions

        :param nonexpressions: a set of identifiers that are legal
         attributes, which cannot contain embedded expressions

        :param \**kwargs:
         other arguments passed to the Node superclass (lineno, pos)

        """
        super(Tag, self).__init__(**kwargs)
        self.keyword = keyword
        self.attributes = attributes
        self._parse_attributes(expressions, nonexpressions)
        missing = [r for r in required if r not in self.parsed_attributes]
        if len(missing):
            raise exceptions.CompileException(
                "Missing attribute(s): %s" %
                    ",".join([repr(m) for m in missing]),
                **self.exception_kwargs)
        self.parent = None
        self.nodes = []

    def is_root(self):
        return self.parent is None

    def get_children(self):
        return self.nodes

    def _parse_attributes(self, expressions, nonexpressions):
        undeclared_identifiers = set()
        self.parsed_attributes = {}
        for key in self.attributes:
            if key in expressions:
                expr = []
                for x in re.compile(r'(\${.+?})',
                                    re.S).split(self.attributes[key]):
                    m = re.compile(r'^\${(.+?)}$', re.S).match(x)
                    if m:
                        code = ast.PythonCode(m.group(1).rstrip(),
                                **self.exception_kwargs)
                        # we aren't discarding "declared_identifiers" here,
                        # which we do so that list comprehension-declared
                        # variables aren't counted.   As yet can't find a
                        # condition that requires it here.
                        undeclared_identifiers = \
                            undeclared_identifiers.union(
                                    code.undeclared_identifiers)
                        expr.append('(%s)' % m.group(1))
                    else:
                        if x:
                            expr.append(repr(x))
                self.parsed_attributes[key] = " + ".join(expr) or repr('')
            elif key in nonexpressions:
                if re.search(r'\${.+?}', self.attributes[key]):
                    raise exceptions.CompileException(
                           "Attibute '%s' in tag '%s' does not allow embedded "
                           "expressions"  % (key, self.keyword),
                           **self.exception_kwargs)
                self.parsed_attributes[key] = repr(self.attributes[key])
            else:
                raise exceptions.CompileException(
                                    "Invalid attribute for tag '%s': '%s'" %
                                    (self.keyword, key),
                                    **self.exception_kwargs)
        self.expression_undeclared_identifiers = undeclared_identifiers

    def declared_identifiers(self):
        return []

    def undeclared_identifiers(self):
        return self.expression_undeclared_identifiers

    def __repr__(self):
        return "%s(%r, %s, %r, %r)" % (self.__class__.__name__,
                                    self.keyword,
                                    util.sorted_dict_repr(self.attributes),
                                    (self.lineno, self.pos),
                                    self.nodes
                                )

class IncludeTag(Tag):
    __keyword__ = 'include'

    def __init__(self, keyword, attributes, **kwargs):
        super(IncludeTag, self).__init__(
                                    keyword,
                                    attributes,
                                    ('file', 'import', 'args'),
                                    (), ('file',), **kwargs)
        self.page_args = ast.PythonCode(
                                "__DUMMY(%s)" % attributes.get('args', ''),
                                 **self.exception_kwargs)

    def declared_identifiers(self):
        return []

    def undeclared_identifiers(self):
        identifiers = self.page_args.undeclared_identifiers.\
                            difference(set(["__DUMMY"])).\
                            difference(self.page_args.declared_identifiers)
        return identifiers.union(super(IncludeTag, self).
                                    undeclared_identifiers())

class NamespaceTag(Tag):
    __keyword__ = 'namespace'

    def __init__(self, keyword, attributes, **kwargs):
        super(NamespaceTag, self).__init__(
                                        keyword, attributes,
                                        ('file',),
                                        ('name','inheritable',
                                        'import','module'),
                                        (), **kwargs)

        self.name = attributes.get('name', '__anon_%s' % hex(abs(id(self))))
        if not 'name' in attributes and not 'import' in attributes:
            raise exceptions.CompileException(
                "'name' and/or 'import' attributes are required "
                "for <%namespace>",
                **self.exception_kwargs)
        if 'file' in attributes and 'module' in attributes:
            raise exceptions.CompileException(
                "<%namespace> may only have one of 'file' or 'module'",
                **self.exception_kwargs
            )

    def declared_identifiers(self):
        return []

class TextTag(Tag):
    __keyword__ = 'text'

    def __init__(self, keyword, attributes, **kwargs):
        super(TextTag, self).__init__(
                                    keyword,
                                    attributes, (),
                                    ('filter'), (), **kwargs)
        self.filter_args = ast.ArgumentList(
                                    attributes.get('filter', ''),
                                    **self.exception_kwargs)

    def undeclared_identifiers(self):
        return self.filter_args.\
                            undeclared_identifiers.\
                            difference(filters.DEFAULT_ESCAPES.keys()).union(
                        self.expression_undeclared_identifiers
                    )

class DefTag(Tag):
    __keyword__ = 'def'

    def __init__(self, keyword, attributes, **kwargs):
        expressions = ['buffered', 'cached'] + [
                c for c in attributes if c.startswith('cache_')]


        super(DefTag, self).__init__(
                keyword,
                attributes,
                expressions,
                ('name', 'filter', 'decorator'),
                ('name',),
                **kwargs)
        name = attributes['name']
        if re.match(r'^[\w_]+$', name):
            raise exceptions.CompileException(
                                "Missing parenthesis in %def",
                                **self.exception_kwargs)
        self.function_decl = ast.FunctionDecl("def " + name + ":pass",
                                                    **self.exception_kwargs)
        self.name = self.function_decl.funcname
        self.decorator = attributes.get('decorator', '')
        self.filter_args = ast.ArgumentList(
                                attributes.get('filter', ''),
                                **self.exception_kwargs)

    is_anonymous = False
    is_block = False

    @property
    def funcname(self):
        return self.function_decl.funcname

    def get_argument_expressions(self, **kw):
        return self.function_decl.get_argument_expressions(**kw)

    def declared_identifiers(self):
        return self.function_decl.allargnames

    def undeclared_identifiers(self):
        res = []
        for c in self.function_decl.defaults:
            res += list(ast.PythonCode(c, **self.exception_kwargs).
                                    undeclared_identifiers)
        return set(res).union(
            self.filter_args.\
                            undeclared_identifiers.\
                            difference(filters.DEFAULT_ESCAPES.keys())
        ).union(
            self.expression_undeclared_identifiers
        ).difference(
            self.function_decl.allargnames
        )

class BlockTag(Tag):
    __keyword__ = 'block'

    def __init__(self, keyword, attributes, **kwargs):
        expressions = ['buffered', 'cached', 'args'] + [
                 c for c in attributes if c.startswith('cache_')]

        super(BlockTag, self).__init__(
                keyword,
                attributes,
                expressions,
                ('name','filter', 'decorator'),
                (),
                **kwargs)
        name = attributes.get('name')
        if name and not re.match(r'^[\w_]+$',name):
            raise exceptions.CompileException(
                               "%block may not specify an argument signature",
                               **self.exception_kwargs)
        if not name and attributes.get('args', None):
            raise exceptions.CompileException(
                                "Only named %blocks may specify args",
                                **self.exception_kwargs
                                )
        self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
                                            **self.exception_kwargs)

        self.name = name
        self.decorator = attributes.get('decorator', '')
        self.filter_args = ast.ArgumentList(
                                attributes.get('filter', ''),
                                **self.exception_kwargs)


    is_block = True

    @property
    def is_anonymous(self):
        return self.name is None

    @property
    def funcname(self):
        return self.name or "__M_anon_%d" % (self.lineno, )

    def get_argument_expressions(self, **kw):
        return self.body_decl.get_argument_expressions(**kw)

    def declared_identifiers(self):
        return self.body_decl.allargnames

    def undeclared_identifiers(self):
        return (self.filter_args.\
                            undeclared_identifiers.\
                            difference(filters.DEFAULT_ESCAPES.keys())
                ).union(self.expression_undeclared_identifiers)



class CallTag(Tag):
    __keyword__ = 'call'

    def __init__(self, keyword, attributes, **kwargs):
        super(CallTag, self).__init__(keyword, attributes,
                                    ('args'), ('expr',), ('expr',), **kwargs)
        self.expression = attributes['expr']
        self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
        self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
                                            **self.exception_kwargs)

    def declared_identifiers(self):
        return self.code.declared_identifiers.union(self.body_decl.allargnames)

    def undeclared_identifiers(self):
        return self.code.undeclared_identifiers.\
                    difference(self.code.declared_identifiers)

class CallNamespaceTag(Tag):

    def __init__(self, namespace, defname, attributes, **kwargs):
        super(CallNamespaceTag, self).__init__(
                    namespace + ":" + defname,
                    attributes,
                    tuple(attributes.keys()) + ('args', ),
                    (),
                    (),
                    **kwargs)

        self.expression = "%s.%s(%s)" % (
                                namespace,
                                defname,
                                ",".join(["%s=%s" % (k, v) for k, v in
                                            self.parsed_attributes.items()
                                            if k != 'args'])
                            )
        self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
        self.body_decl = ast.FunctionArgs(
                                    attributes.get('args', ''),
                                    **self.exception_kwargs)

    def declared_identifiers(self):
        return self.code.declared_identifiers.union(self.body_decl.allargnames)

    def undeclared_identifiers(self):
        return self.code.undeclared_identifiers.\
                    difference(self.code.declared_identifiers)

class InheritTag(Tag):
    __keyword__ = 'inherit'

    def __init__(self, keyword, attributes, **kwargs):
        super(InheritTag, self).__init__(
                                keyword, attributes,
                                ('file',), (), ('file',), **kwargs)

class PageTag(Tag):
    __keyword__ = 'page'

    def __init__(self, keyword, attributes, **kwargs):
        expressions =   ['cached', 'args', 'expression_filter', 'enable_loop'] + [
                    c for c in attributes if c.startswith('cache_')]

        super(PageTag, self).__init__(
                keyword,
                attributes,
                expressions,
                (),
                (),
                **kwargs)
        self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
                                            **self.exception_kwargs)
        self.filter_args = ast.ArgumentList(
                                attributes.get('expression_filter', ''),
                                **self.exception_kwargs)

    def declared_identifiers(self):
        return self.body_decl.allargnames


