# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of astroid.
#
# astroid 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.
#
# astroid 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 astroid. If not, see <http://www.gnu.org/licenses/>.
"""Module for some node classes. More nodes in scoped_nodes.py
"""

import sys

from astroid.exceptions import NoDefault
from astroid.bases import (NodeNG, Statement, Instance, InferenceContext,
                           _infer_stmts, YES, BUILTINS)
from astroid.mixins import (BlockRangeMixIn, AssignTypeMixin,
                            ParentAssignTypeMixin, FromImportMixIn)

PY3K = sys.version_info >= (3, 0)


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
    # if infered is a final node, return it and stop
    infered = stmt.infer(context).next()
    if infered is stmt:
        yield infered
        return
    # else, infer recursivly, except YES object that should be returned as is
    for infered in stmt.infer(context):
        if infered is YES:
            yield infered
        else:
            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"""
    if PY3K:
        # Python 3.4+ uses a different approach regarding annotations,
        # each argument is a new class, _ast.arg, which exposes an
        # 'annotation' attribute. In astroid though, arguments are exposed
        # as is in the Arguments node and the only way to expose annotations
        # is by using something similar with Python 3.3:
        #  - we expose 'varargannotation' and 'kwargannotation' of annotations
        #    of varargs and kwargs.
        #  - we expose 'annotation', a list with annotations for
        #    for each normal argument. If an argument doesn't have an
        #    annotation, its value will be None.

        _astroid_fields = ('args', 'defaults', 'kwonlyargs',
                           'kw_defaults', 'annotations',
                           'varargannotation', 'kwargannotation')
        annotations = None
        varargannotation = None
        kwargannotation = None
    else:
        _astroid_fields = ('args', 'defaults', 'kwonlyargs', 'kw_defaults')
    args = None
    defaults = None
    kwonlyargs = None
    kw_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 = []
        if self.args:
            result.append(_format_args(self.args, self.defaults))
        if self.vararg:
            result.append('*%s' % self.vararg)
        if self.kwarg:
            result.append('**%s' % self.kwarg)
        if self.kwonlyargs:
            if not self.vararg:
                result.append('*')
            result.append(_format_args(self.kwonlyargs, self.kw_defaults))
        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]
        i = _find_arg(argname, self.kwonlyargs)[0]
        if i is not None and self.kw_defaults[i] is not None:
            return self.kw_defaults[i]
        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 get_children(self):
        """override get_children to skip over None elements in kw_defaults"""
        for child in super(Arguments, self).get_children():
            if child is not None:
                yield child


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:
                if defaults[i-default_offset] is not None:
                    values[-1] += '=' + defaults[i-default_offset].as_string()
    return ', '.join(values)


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

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

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

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

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

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

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

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


class CallFunc(NodeNG):
    """class representing a CallFunc node"""
    _astroid_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"""
    _astroid_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"""
    _astroid_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"""
    _astroid_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"""
    _astroid_fields = ('expr',)
    expr = None


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


class Dict(NodeNG, Instance):
    """class representing a Dict node"""
    _astroid_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

    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, lookup_key, context=None):
        for key, value in self.items:
            for inferedkey in key.infer(context):
                if inferedkey is YES:
                    continue
                if isinstance(inferedkey, Const) \
                        and inferedkey.value == lookup_key:
                    return value
        # This should raise KeyError, but all call sites only catch
        # IndexError. Let's leave it like that for now.
        raise IndexError(lookup_key)


class Discard(Statement):
    """class representing a Discard node"""
    _astroid_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"""
    _astroid_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"""
    _astroid_fields = ('expr', 'globals', 'locals',)
    expr = None
    globals = None
    locals = None


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

class For(BlockRangeMixIn, AssignTypeMixin, Statement):
    """class representing a For node"""
    _astroid_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"""
    _astroid_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"""
    _astroid_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"""
    _astroid_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"""
    _astroid_fields = ('value',)
    value = None


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


class List(NodeNG, Instance, ParentAssignTypeMixin):
    """class representing a List node"""
    _astroid_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

    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"""
    _astroid_fields = ('dest', 'values',)
    dest = None
    values = None


class Raise(Statement):
    """class representing a Raise node"""
    exc = None
    if sys.version_info < (3, 0):
        _astroid_fields = ('exc', 'inst', 'tback')
        inst = None
        tback = None
    else:
        _astroid_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"""
    _astroid_fields = ('value',)
    value = None


class Set(NodeNG, Instance, ParentAssignTypeMixin):
    """class representing a Set node"""
    _astroid_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

    def itered(self):
        return self.elts


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

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


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


class TryExcept(BlockRangeMixIn, Statement):
    """class representing a TryExcept node"""
    _astroid_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"""
    _astroid_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"""
    _astroid_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

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

    def itered(self):
        return self.elts


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


class While(BlockRangeMixIn, Statement):
    """class representing a While node"""
    _astroid_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"""
    _astroid_fields = ('items', 'body')
    items = None
    body = None

    def _blockstart_toline(self):
        return self.items[-1][0].tolineno

    def get_children(self):
        for expr, var in self.items:
            yield expr
            if var:
                yield var
        for elt in self.body:
            yield elt

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

class YieldFrom(Yield):
    """ Class representing a YieldFrom node. """

# 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 astroid node for a python value"""
    # XXX we should probably be stricter here and only consider stuff in
    # CONST_CLS or do better treatment: in case where value is not in CONST_CLS,
    # we should rather recall the builder on this value than returning an empty
    # node (another option being that const_factory shouldn't be called with something
    # not in CONST_CLS)
    assert not isinstance(value, NodeNG)
    try:
        return CONST_CLS[value.__class__](value)
    except (KeyError, AttributeError):
        node = EmptyNode()
        node.object = value
        return node
