# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
#
# This file is part of logilab-astng.
#
# logilab-astng is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version.
#
# logilab-astng is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>.
"""Module for some node classes. More nodes in scoped_nodes.py
"""

import sys

from logilab.astng import BUILTINS_MODULE
from logilab.astng.exceptions import NoDefault
from logilab.astng.bases import (NodeNG, Statement, Instance, InferenceContext,
                                 _infer_stmts, YES)
from logilab.astng.mixins import BlockRangeMixIn, AssignTypeMixin, \
                                 ParentAssignTypeMixin, FromImportMixIn


def unpack_infer(stmt, context=None):
    """recursively generate nodes inferred by the given statement.
    If the inferred value is a list or a tuple, recurse on the elements
    """
    if isinstance(stmt, (List, Tuple)):
        for elt in stmt.elts:
            for infered_elt in unpack_infer(elt, context):
                yield infered_elt
        return
    infered = stmt.infer(context).next()
    if infered is stmt or infered is YES:
        yield infered
        return
    for infered in stmt.infer(context):
        for inf_inf in unpack_infer(infered, context):
            yield inf_inf


def are_exclusive(stmt1, stmt2, exceptions=None):
    """return true if the two given statements are mutually exclusive

    `exceptions` may be a list of exception names. If specified, discard If
    branches and check one of the statement is in an exception handler catching
    one of the given exceptions.

    algorithm :
     1) index stmt1's parents
     2) climb among stmt2's parents until we find a common parent
     3) if the common parent is a If or TryExcept statement, look if nodes are
        in exclusive branches
    """
    # index stmt1's parents
    stmt1_parents = {}
    children = {}
    node = stmt1.parent
    previous = stmt1
    while node:
        stmt1_parents[node] = 1
        children[node] = previous
        previous = node
        node = node.parent
    # climb among stmt2's parents until we find a common parent
    node = stmt2.parent
    previous = stmt2
    while node:
        if node in stmt1_parents:
            # if the common parent is a If or TryExcept statement, look if
            # nodes are in exclusive branches
            if isinstance(node, If) and exceptions is None:
                if (node.locate_child(previous)[1]
                    is not node.locate_child(children[node])[1]):
                    return True
            elif isinstance(node, TryExcept):
                c2attr, c2node = node.locate_child(previous)
                c1attr, c1node = node.locate_child(children[node])
                if c1node is not c2node:
                    if ((c2attr == 'body' and c1attr == 'handlers' and children[node].catch(exceptions)) or
                        (c2attr == 'handlers' and c1attr == 'body' and previous.catch(exceptions)) or
                        (c2attr == 'handlers' and c1attr == 'orelse') or
                        (c2attr == 'orelse' and c1attr == 'handlers')):
                        return True
                elif c2attr == 'handlers' and c1attr == 'handlers':
                    return previous is not children[node]
            return False
        previous = node
        node = node.parent
    return False


class LookupMixIn(object):
    """Mixin looking up a name in the right scope
    """

    def lookup(self, name):
        """lookup a variable name

        return the scope node and the list of assignments associated to the given
        name according to the scope where it has been found (locals, globals or
        builtin)

        The lookup is starting from self's scope. If self is not a frame itself and
        the name is found in the inner frame locals, statements will be filtered
        to remove ignorable statements according to self's location
        """
        return self.scope().scope_lookup(self, name)

    def ilookup(self, name):
        """infered lookup

        return an iterator on infered values of the statements returned by
        the lookup method
        """
        frame, stmts = self.lookup(name)
        context = InferenceContext()
        return _infer_stmts(stmts, context, frame)

    def _filter_stmts(self, stmts, frame, offset):
        """filter statements to remove ignorable statements.

        If self is not a frame itself and the name is found in the inner
        frame locals, statements will be filtered to remove ignorable
        statements according to self's location
        """
        # if offset == -1, my actual frame is not the inner frame but its parent
        #
        # class A(B): pass
        #
        # we need this to resolve B correctly
        if offset == -1:
            myframe = self.frame().parent.frame()
        else:
            myframe = self.frame()
        if not myframe is frame or self is frame:
            return stmts
        mystmt = self.statement()
        # line filtering if we are in the same frame
        #
        # take care node may be missing lineno information (this is the case for
        # nodes inserted for living objects)
        if myframe is frame and mystmt.fromlineno is not None:
            assert mystmt.fromlineno is not None, mystmt
            mylineno = mystmt.fromlineno + offset
        else:
            # disabling lineno filtering
            mylineno = 0
        _stmts = []
        _stmt_parents = []
        for node in stmts:
            stmt = node.statement()
            # line filtering is on and we have reached our location, break
            if mylineno > 0 and stmt.fromlineno > mylineno:
                break
            assert hasattr(node, 'ass_type'), (node, node.scope(),
                                               node.scope().locals)
            ass_type = node.ass_type()

            if node.has_base(self):
                break

            _stmts, done = ass_type._get_filtered_stmts(self, node, _stmts, mystmt)
            if done:
                break

            optional_assign = ass_type.optional_assign
            if optional_assign and ass_type.parent_of(self):
                # we are inside a loop, loop var assigment is hidding previous
                # assigment
                _stmts = [node]
                _stmt_parents = [stmt.parent]
                continue

            # XXX comment various branches below!!!
            try:
                pindex = _stmt_parents.index(stmt.parent)
            except ValueError:
                pass
            else:
                # we got a parent index, this means the currently visited node
                # is at the same block level as a previously visited node
                if _stmts[pindex].ass_type().parent_of(ass_type):
                    # both statements are not at the same block level
                    continue
                # if currently visited node is following previously considered
                # assignement and both are not exclusive, we can drop the
                # previous one. For instance in the following code ::
                #
                #   if a:
                #     x = 1
                #   else:
                #     x = 2
                #   print x
                #
                # we can't remove neither x = 1 nor x = 2 when looking for 'x'
                # of 'print x'; while in the following ::
                #
                #   x = 1
                #   x = 2
                #   print x
                #
                # we can remove x = 1 when we see x = 2
                #
                # moreover, on loop assignment types, assignment won't
                # necessarily be done if the loop has no iteration, so we don't
                # want to clear previous assigments if any (hence the test on
                # optional_assign)
                if not (optional_assign or are_exclusive(_stmts[pindex], node)):
                    del _stmt_parents[pindex]
                    del _stmts[pindex]
            if isinstance(node, AssName):
                if not optional_assign and stmt.parent is mystmt.parent:
                    _stmts = []
                    _stmt_parents = []
            elif isinstance(node, DelName):
                _stmts = []
                _stmt_parents = []
                continue
            if not are_exclusive(self, node):
                _stmts.append(node)
                _stmt_parents.append(stmt.parent)
        return _stmts

# Name classes

class AssName(LookupMixIn, ParentAssignTypeMixin, NodeNG):
    """class representing an AssName node"""


class DelName(LookupMixIn, ParentAssignTypeMixin, NodeNG):
    """class representing a DelName node"""


class Name(LookupMixIn, NodeNG):
    """class representing a Name node"""




#####################   node classes   ########################################

class Arguments(NodeNG, AssignTypeMixin):
    """class representing an Arguments node"""
    _astng_fields = ('args', 'defaults')
    args = None
    defaults = None

    def __init__(self, vararg=None, kwarg=None):
        self.vararg = vararg
        self.kwarg = kwarg

    def _infer_name(self, frame, name):
        if self.parent is frame:
            return name
        return None

    def format_args(self):
        """return arguments formatted as string"""
        result = [_format_args(self.args, self.defaults)]
        if self.vararg:
            result.append('*%s' % self.vararg)
        if self.kwarg:
            result.append('**%s' % self.kwarg)
        return ', '.join(result)

    def default_value(self, argname):
        """return the default value for an argument

        :raise `NoDefault`: if there is no default value defined
        """
        i = _find_arg(argname, self.args)[0]
        if i is not None:
            idx = i - (len(self.args) - len(self.defaults))
            if idx >= 0:
                return self.defaults[idx]
        raise NoDefault()

    def is_argument(self, name):
        """return True if the name is defined in arguments"""
        if name == self.vararg:
            return True
        if name == self.kwarg:
            return True
        return self.find_argname(name, True)[1] is not None

    def find_argname(self, argname, rec=False):
        """return index and Name node with given name"""
        if self.args: # self.args may be None in some cases (builtin function)
            return _find_arg(argname, self.args, rec)
        return None, None


def _find_arg(argname, args, rec=False):
    for i, arg in enumerate(args):
        if isinstance(arg, Tuple):
            if rec:
                found = _find_arg(argname, arg.elts)
                if found[0] is not None:
                    return found
        elif arg.name == argname:
            return i, arg
    return None, None


def _format_args(args, defaults=None):
    values = []
    if args is None:
        return ''
    if defaults is not None:
        default_offset = len(args) - len(defaults)
    for i, arg in enumerate(args):
        if isinstance(arg, Tuple):
            values.append('(%s)' % _format_args(arg.elts))
        else:
            values.append(arg.name)
            if defaults is not None and i >= default_offset:
                values[-1] += '=' + defaults[i-default_offset].as_string()
    return ', '.join(values)


class AssAttr(NodeNG, ParentAssignTypeMixin):
    """class representing an AssAttr node"""
    _astng_fields = ('expr',)
    expr = None

class Assert(Statement):
    """class representing an Assert node"""
    _astng_fields = ('test', 'fail',)
    test = None
    fail = None

class Assign(Statement, AssignTypeMixin):
    """class representing an Assign node"""
    _astng_fields = ('targets', 'value',)
    targets = None
    value = None

class AugAssign(Statement, AssignTypeMixin):
    """class representing an AugAssign node"""
    _astng_fields = ('target', 'value',)
    target = None
    value = None

class Backquote(NodeNG):
    """class representing a Backquote node"""
    _astng_fields = ('value',)
    value = None

class BinOp(NodeNG):
    """class representing a BinOp node"""
    _astng_fields = ('left', 'right',)
    left = None
    right = None

class BoolOp(NodeNG):
    """class representing a BoolOp node"""
    _astng_fields = ('values',)
    values = None

class Break(Statement):
    """class representing a Break node"""


class CallFunc(NodeNG):
    """class representing a CallFunc node"""
    _astng_fields = ('func', 'args', 'starargs', 'kwargs')
    func = None
    args = None
    starargs = None
    kwargs = None

    def __init__(self):
        self.starargs = None
        self.kwargs = None

class Compare(NodeNG):
    """class representing a Compare node"""
    _astng_fields = ('left', 'ops',)
    left = None
    ops = None

    def get_children(self):
        """override get_children for tuple fields"""
        yield self.left
        for _, comparator in self.ops:
            yield comparator # we don't want the 'op'

    def last_child(self):
        """override last_child"""
        # XXX maybe if self.ops:
        return self.ops[-1][1]
        #return self.left

class Comprehension(NodeNG):
    """class representing a Comprehension node"""
    _astng_fields = ('target', 'iter' ,'ifs')
    target = None
    iter = None
    ifs = None

    optional_assign = True
    def ass_type(self):
        return self

    def _get_filtered_stmts(self, lookup_node, node, stmts, mystmt):
        """method used in filter_stmts"""
        if self is mystmt:
            if isinstance(lookup_node, (Const, Name)):
                return [lookup_node], True

        elif self.statement() is mystmt:
            # original node's statement is the assignment, only keeps
            # current node (gen exp, list comp)

            return [node], True

        return stmts, False


class Const(NodeNG, Instance):
    """represent a constant node like num, str, bool, None, bytes"""

    def __init__(self, value=None):
        self.value = value

    def getitem(self, index, context=None):
        if isinstance(self.value, basestring):
            return Const(self.value[index])
        raise TypeError('%r (value=%s)' % (self, self.value))

    def has_dynamic_getattr(self):
        return False

    def itered(self):
        if isinstance(self.value, basestring):
            return self.value
        raise TypeError()

    def pytype(self):
        return self._proxied.qname()


class Continue(Statement):
    """class representing a Continue node"""


class Decorators(NodeNG):
    """class representing a Decorators node"""
    _astng_fields = ('nodes',)
    nodes = None

    def __init__(self, nodes=None):
        self.nodes = nodes

    def scope(self):
        # skip the function node to go directly to the upper level scope
        return self.parent.parent.scope()

class DelAttr(NodeNG, ParentAssignTypeMixin):
    """class representing a DelAttr node"""
    _astng_fields = ('expr',)
    expr = None


class Delete(Statement, AssignTypeMixin):
    """class representing a Delete node"""
    _astng_fields = ('targets',)
    targets = None


class Dict(NodeNG, Instance):
    """class representing a Dict node"""
    _astng_fields = ('items',)

    def __init__(self, items=None):
        if items is None:
            self.items = []
        else:
            self.items = [(const_factory(k), const_factory(v))
                          for k,v in items.iteritems()]

    def pytype(self):
        return '%s.dict' % BUILTINS_MODULE

    def get_children(self):
        """get children of a Dict node"""
        # overrides get_children
        for key, value in self.items:
            yield key
            yield value

    def last_child(self):
        """override last_child"""
        if self.items:
            return self.items[-1][1]
        return None

    def itered(self):
        return self.items[::2]

    def getitem(self, key, context=None):
        for i in xrange(0, len(self.items), 2):
            for inferedkey in self.items[i].infer(context):
                if inferedkey is YES:
                    continue
                if isinstance(inferedkey, Const) and inferedkey.value == key:
                    return self.items[i+1]
        raise IndexError(key)


class Discard(Statement):
    """class representing a Discard node"""
    _astng_fields = ('value',)
    value = None


class Ellipsis(NodeNG):
    """class representing an Ellipsis node"""


class EmptyNode(NodeNG):
    """class representing an EmptyNode node"""


class ExceptHandler(Statement, AssignTypeMixin):
    """class representing an ExceptHandler node"""
    _astng_fields = ('type', 'name', 'body',)
    type = None
    name = None
    body = None

    def _blockstart_toline(self):
        if self.name:
            return self.name.tolineno
        elif self.type:
            return self.type.tolineno
        else:
            return self.lineno

    def set_line_info(self, lastchild):
        self.fromlineno = self.lineno
        self.tolineno = lastchild.tolineno
        self.blockstart_tolineno = self._blockstart_toline()

    def catch(self, exceptions):
        if self.type is None or exceptions is None:
            return True
        for node in self.type.nodes_of_class(Name):
            if node.name in exceptions:
                return True


class Exec(Statement):
    """class representing an Exec node"""
    _astng_fields = ('expr', 'globals', 'locals',)
    expr = None
    globals = None
    locals = None


class ExtSlice(NodeNG):
    """class representing an ExtSlice node"""
    _astng_fields = ('dims',)
    dims = None

class For(BlockRangeMixIn, AssignTypeMixin, Statement):
    """class representing a For node"""
    _astng_fields = ('target', 'iter', 'body', 'orelse',)
    target = None
    iter = None
    body = None
    orelse = None

    optional_assign = True
    def _blockstart_toline(self):
        return self.iter.tolineno


class From(FromImportMixIn, Statement):
    """class representing a From node"""

    def __init__(self,  fromname, names, level=0):
        self.modname = fromname
        self.names = names
        self.level = level

class Getattr(NodeNG):
    """class representing a Getattr node"""
    _astng_fields = ('expr',)
    expr = None


class Global(Statement):
    """class representing a Global node"""

    def __init__(self, names):
        self.names = names

    def _infer_name(self, frame, name):
        return name


class If(BlockRangeMixIn, Statement):
    """class representing an If node"""
    _astng_fields = ('test', 'body', 'orelse')
    test = None
    body = None
    orelse = None

    def _blockstart_toline(self):
        return self.test.tolineno

    def block_range(self, lineno):
        """handle block line numbers range for if statements"""
        if lineno == self.body[0].fromlineno:
            return lineno, lineno
        if lineno <= self.body[-1].tolineno:
            return lineno, self.body[-1].tolineno
        return self._elsed_block_range(lineno, self.orelse,
                                       self.body[0].fromlineno - 1)


class IfExp(NodeNG):
    """class representing an IfExp node"""
    _astng_fields = ('test', 'body', 'orelse')
    test = None
    body = None
    orelse = None


class Import(FromImportMixIn, Statement):
    """class representing an Import node"""


class Index(NodeNG):
    """class representing an Index node"""
    _astng_fields = ('value',)
    value = None


class Keyword(NodeNG):
    """class representing a Keyword node"""
    _astng_fields = ('value',)
    value = None


class List(NodeNG, Instance, ParentAssignTypeMixin):
    """class representing a List node"""
    _astng_fields = ('elts',)

    def __init__(self, elts=None):
        if elts is None:
            self.elts = []
        else:
            self.elts = [const_factory(e) for e in elts]

    def pytype(self):
        return '%s.list' % BUILTINS_MODULE

    def getitem(self, index, context=None):
        return self.elts[index]

    def itered(self):
        return self.elts


class Nonlocal(Statement):
    """class representing a Nonlocal node"""

    def __init__(self, names):
        self.names = names

    def _infer_name(self, frame, name):
        return name


class Pass(Statement):
    """class representing a Pass node"""


class Print(Statement):
    """class representing a Print node"""
    _astng_fields = ('dest', 'values',)
    dest = None
    values = None


class Raise(Statement):
    """class representing a Raise node"""
    exc = None
    if sys.version_info < (3, 0):
        _astng_fields = ('exc', 'inst', 'tback')
        inst = None
        tback = None
    else:
        _astng_fields = ('exc', 'cause')
        exc = None
        cause = None

    def raises_not_implemented(self):
        if not self.exc:
            return
        for name in self.exc.nodes_of_class(Name):
            if name.name == 'NotImplementedError':
                return True


class Return(Statement):
    """class representing a Return node"""
    _astng_fields = ('value',)
    value = None


class Set(NodeNG, Instance, ParentAssignTypeMixin):
    """class representing a Set node"""
    _astng_fields = ('elts',)

    def __init__(self, elts=None):
        if elts is None:
            self.elts = []
        else:
            self.elts = [const_factory(e) for e in elts]

    def pytype(self):
        return '%s.set' % BUILTINS_MODULE

    def itered(self):
        return self.elts


class Slice(NodeNG):
    """class representing a Slice node"""
    _astng_fields = ('lower', 'upper', 'step')
    lower = None
    upper = None
    step = None

class Starred(NodeNG):
    """class representing a Starred node"""
    _astng_fields = ('value',)
    value = None


class Subscript(NodeNG):
    """class representing a Subscript node"""
    _astng_fields = ('value', 'slice')
    value = None
    slice = None


class TryExcept(BlockRangeMixIn, Statement):
    """class representing a TryExcept node"""
    _astng_fields = ('body', 'handlers', 'orelse',)
    body = None
    handlers = None
    orelse = None

    def _infer_name(self, frame, name):
        return name

    def _blockstart_toline(self):
        return self.lineno

    def block_range(self, lineno):
        """handle block line numbers range for try/except statements"""
        last = None
        for exhandler in self.handlers:
            if exhandler.type and lineno == exhandler.type.fromlineno:
                return lineno, lineno
            if exhandler.body[0].fromlineno <= lineno <= exhandler.body[-1].tolineno:
                return lineno, exhandler.body[-1].tolineno
            if last is None:
                last = exhandler.body[0].fromlineno - 1
        return self._elsed_block_range(lineno, self.orelse, last)


class TryFinally(BlockRangeMixIn, Statement):
    """class representing a TryFinally node"""
    _astng_fields = ('body', 'finalbody',)
    body = None
    finalbody = None

    def _blockstart_toline(self):
        return self.lineno

    def block_range(self, lineno):
        """handle block line numbers range for try/finally statements"""
        child = self.body[0]
        # py2.5 try: except: finally:
        if (isinstance(child, TryExcept) and child.fromlineno == self.fromlineno
            and lineno > self.fromlineno and lineno <= child.tolineno):
            return child.block_range(lineno)
        return self._elsed_block_range(lineno, self.finalbody)


class Tuple(NodeNG, Instance, ParentAssignTypeMixin):
    """class representing a Tuple node"""
    _astng_fields = ('elts',)

    def __init__(self, elts=None):
        if elts is None:
            self.elts = []
        else:
            self.elts = [const_factory(e) for e in elts]

    def pytype(self):
        return '%s.tuple' % BUILTINS_MODULE

    def getitem(self, index, context=None):
        return self.elts[index]

    def itered(self):
        return self.elts


class UnaryOp(NodeNG):
    """class representing an UnaryOp node"""
    _astng_fields = ('operand',)
    operand = None


class While(BlockRangeMixIn, Statement):
    """class representing a While node"""
    _astng_fields = ('test', 'body', 'orelse',)
    test = None
    body = None
    orelse = None

    def _blockstart_toline(self):
        return self.test.tolineno

    def block_range(self, lineno):
        """handle block line numbers range for for and while statements"""
        return self. _elsed_block_range(lineno, self.orelse)


class With(BlockRangeMixIn, AssignTypeMixin, Statement):
    """class representing a With node"""
    _astng_fields = ('expr', 'vars', 'body')
    expr = None
    vars = None
    body = None

    def _blockstart_toline(self):
        if self.vars:
            return self.vars.tolineno
        else:
            return self.expr.tolineno


class Yield(NodeNG):
    """class representing a Yield node"""
    _astng_fields = ('value',)
    value = None

# constants ##############################################################

CONST_CLS = {
    list: List,
    tuple: Tuple,
    dict: Dict,
    set: Set,
    type(None): Const,
    }

def _update_const_classes():
    """update constant classes, so the keys of CONST_CLS can be reused"""
    klasses = (bool, int, float, complex, str)
    if sys.version_info < (3, 0):
        klasses += (unicode, long)
    if sys.version_info >= (2, 6):
        klasses += (bytes,)
    for kls in klasses:
        CONST_CLS[kls] = Const
_update_const_classes()

def const_factory(value):
    """return an astng node for a python value"""
    # since const_factory is called to evaluate content of container (eg list,
    # tuple), it may be called with some node as argument that should be left
    # untouched
    if isinstance(value, NodeNG):
        return value
    try:
        return CONST_CLS[value.__class__](value)
    except (KeyError, AttributeError):
        # some constants (like from gtk._gtk) don't have their class in
        # CONST_CLS, though we can "assert isinstance(value, tuple(CONST_CLS))"
        if isinstance(value, tuple(CONST_CLS)):
            return Const(value)
        node = EmptyNode()
        node.object = value
        return node
