# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE
# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt

import sys
import textwrap
import unittest
from unittest import mock

import pytest

from astroid import MANAGER, Instance, bases, manager, nodes, parse, test_utils
from astroid.builder import AstroidBuilder, _extract_single_node, extract_node
from astroid.context import InferenceContext
from astroid.exceptions import InferenceError
from astroid.raw_building import build_module
from astroid.util import Uninferable

from . import resources

try:
    import numpy  # pylint: disable=unused-import
except ImportError:
    HAS_NUMPY = False
else:
    HAS_NUMPY = True


class NonRegressionTests(resources.AstroidCacheSetupMixin, unittest.TestCase):
    def setUp(self) -> None:
        sys.path.insert(0, resources.find("data"))
        MANAGER.always_load_extensions = True

    def tearDown(self) -> None:
        MANAGER.always_load_extensions = False
        sys.path.pop(0)
        sys.path_importer_cache.pop(resources.find("data"), None)

    def test_manager_instance_attributes_reference_global_MANAGER(self) -> None:
        for expected in (True, False):
            with mock.patch.dict(
                manager.AstroidManager.brain,
                values={"always_load_extensions": expected},
            ):
                assert (
                    MANAGER.always_load_extensions
                    == manager.AstroidManager.brain["always_load_extensions"]
                )
            with mock.patch.dict(
                manager.AstroidManager.brain,
                values={"optimize_ast": expected},
            ):
                assert (
                    MANAGER.optimize_ast == manager.AstroidManager.brain["optimize_ast"]
                )

    def test_module_path(self) -> None:
        man = test_utils.brainless_manager()
        mod = man.ast_from_module_name("package.import_package_subpackage_module")
        package = next(mod.igetattr("package"))
        self.assertEqual(package.name, "package")
        subpackage = next(package.igetattr("subpackage"))
        self.assertIsInstance(subpackage, nodes.Module)
        self.assertTrue(subpackage.package)
        self.assertEqual(subpackage.name, "package.subpackage")
        module = next(subpackage.igetattr("module"))
        self.assertEqual(module.name, "package.subpackage.module")

    def test_package_sidepackage(self) -> None:
        brainless_manager = test_utils.brainless_manager()
        assert "package.sidepackage" not in MANAGER.astroid_cache
        package = brainless_manager.ast_from_module_name("absimp")
        self.assertIsInstance(package, nodes.Module)
        self.assertTrue(package.package)
        subpackage = next(package.getattr("sidepackage")[0].infer())
        self.assertIsInstance(subpackage, nodes.Module)
        self.assertTrue(subpackage.package)
        self.assertEqual(subpackage.name, "absimp.sidepackage")

    def test_living_property(self) -> None:
        builder = AstroidBuilder()
        builder._done = {}
        builder._module = sys.modules[__name__]
        builder.object_build(build_module("module_name", ""), Whatever)

    @unittest.skipIf(not HAS_NUMPY, "Needs numpy")
    def test_numpy_crash(self):
        """Test don't crash on numpy."""
        # a crash occurred somewhere in the past, and an
        # InferenceError instead of a crash was better, but now we even infer!
        builder = AstroidBuilder()
        data = """
from numpy import multiply

multiply([1, 2], [3, 4])
"""
        astroid = builder.string_build(data, __name__, __file__)
        callfunc = astroid.body[1].value.func
        inferred = callfunc.inferred()
        self.assertEqual(len(inferred), 1)

    @unittest.skipUnless(HAS_NUMPY, "Needs numpy")
    def test_numpy_distutils(self):
        """Special handling of virtualenv's patching of distutils shouldn't interfere
        with numpy.distutils.

        PY312_PLUS -- This test will likely become unnecessary when Python 3.12 is
        numpy's minimum version. (numpy.distutils will be removed then.)
        """
        node = extract_node(
            """
from numpy.distutils.misc_util import is_sequence
is_sequence("ABC") #@
"""
        )
        inferred = node.inferred()
        self.assertIsInstance(inferred[0], nodes.Const)

    def test_nameconstant(self) -> None:
        # used to fail for Python 3.4
        builder = AstroidBuilder()
        astroid = builder.string_build("def test(x=True): pass")
        default = astroid.body[0].args.args[0]
        self.assertEqual(default.name, "x")
        self.assertEqual(next(default.infer()).value, True)

    def test_recursion_regression_issue25(self) -> None:
        builder = AstroidBuilder()
        data = """
import recursion as base

_real_Base = base.Base

class Derived(_real_Base):
    pass

def run():
    base.Base = Derived
"""
        astroid = builder.string_build(data, __name__, __file__)
        # Used to crash in _is_metaclass, due to wrong
        # ancestors chain
        classes = astroid.nodes_of_class(nodes.ClassDef)
        for klass in classes:
            # triggers the _is_metaclass call
            klass.type  # pylint: disable=pointless-statement  # noqa: B018

    def test_decorator_callchain_issue42(self) -> None:
        builder = AstroidBuilder()
        data = """

def test():
    def factory(func):
        def newfunc():
            func()
        return newfunc
    return factory

@test()
def crash():
    pass
"""
        astroid = builder.string_build(data, __name__, __file__)
        self.assertEqual(astroid["crash"].type, "function")

    def test_filter_stmts_scoping(self) -> None:
        builder = AstroidBuilder()
        data = """
def test():
    compiler = int()
    class B(compiler.__class__):
        pass
    compiler = B()
    return compiler
"""
        astroid = builder.string_build(data, __name__, __file__)
        test = astroid["test"]
        result = next(test.infer_call_result(astroid))
        self.assertIsInstance(result, Instance)
        base = next(result._proxied.bases[0].infer())
        self.assertEqual(base.name, "int")

    def test_filter_stmts_nested_if(self) -> None:
        builder = AstroidBuilder()
        data = """
def test(val):
    variable = None

    if val == 1:
        variable = "value"
        if variable := "value":
            pass

    elif val == 2:
        variable = "value_two"
        variable = "value_two"

    return variable
"""
        module = builder.string_build(data, __name__, __file__)
        test_func = module["test"]
        result = list(test_func.infer_call_result(module))
        assert len(result) == 3
        assert isinstance(result[0], nodes.Const)
        assert result[0].value is None
        assert result[0].lineno == 3
        assert isinstance(result[1], nodes.Const)
        assert result[1].value == "value"
        assert result[1].lineno == 7
        assert isinstance(result[1], nodes.Const)
        assert result[2].value == "value_two"
        assert result[2].lineno == 12

    def test_ancestors_patching_class_recursion(self) -> None:
        node = AstroidBuilder().string_build(
            textwrap.dedent(
                """
        import string
        Template = string.Template

        class A(Template):
            pass

        class B(A):
            pass

        def test(x=False):
            if x:
                string.Template = A
            else:
                string.Template = B
        """
            )
        )
        klass = node["A"]
        ancestors = list(klass.ancestors())
        self.assertEqual(ancestors[0].qname(), "string.Template")

    def test_ancestors_yes_in_bases(self) -> None:
        # Test for issue https://bitbucket.org/logilab/astroid/issue/84
        # This used to crash astroid with a TypeError, because an Uninferable
        # node was present in the bases
        node = extract_node(
            """
        def with_metaclass(meta, *bases):
            class metaclass(meta):
                def __new__(cls, name, this_bases, d):
                    return meta(name, bases, d)
        return type.__new__(metaclass, 'temporary_class', (), {})

        import lala

        class A(with_metaclass(object, lala.lala)): #@
            pass
        """
        )
        ancestors = list(node.ancestors())
        self.assertEqual(len(ancestors), 1)
        self.assertEqual(ancestors[0].qname(), "builtins.object")

    def test_ancestors_missing_from_function(self) -> None:
        # Test for https://www.logilab.org/ticket/122793
        node = extract_node(
            """
        def gen(): yield
        GEN = gen()
        next(GEN)
        """
        )
        self.assertRaises(InferenceError, next, node.infer())

    def test_unicode_in_docstring(self) -> None:
        # Crashed for astroid==1.4.1
        # Test for https://bitbucket.org/logilab/astroid/issues/273/

        # In a regular file, "coding: utf-8" would have been used.
        node = extract_node(
            f"""
        from __future__ import unicode_literals

        class MyClass(object):
            def method(self):
                "With unicode : {'’'} "

        instance = MyClass()
        """
        )

        next(node.value.infer()).as_string()

    def test_binop_generates_nodes_with_parents(self) -> None:
        node = extract_node(
            """
        def no_op(*args):
            pass
        def foo(*args):
            def inner(*more_args):
                args + more_args #@
            return inner
        """
        )
        inferred = next(node.infer())
        self.assertIsInstance(inferred, nodes.Tuple)
        self.assertIsNotNone(inferred.parent)
        self.assertIsInstance(inferred.parent, nodes.BinOp)

    def test_decorator_names_inference_error_leaking(self) -> None:
        node = extract_node(
            """
        class Parent(object):
            @property
            def foo(self):
                pass

        class Child(Parent):
            @Parent.foo.getter
            def foo(self): #@
                return super(Child, self).foo + ['oink']
        """
        )
        inferred = next(node.infer())
        self.assertEqual(inferred.decoratornames(), {".Parent.foo.getter"})

    def test_recursive_property_method(self) -> None:
        node = extract_node(
            """
        class APropert():
            @property
            def property(self):
                return self
        APropert().property
        """
        )
        next(node.infer())

    def test_uninferable_string_argument_of_namedtuple(self) -> None:
        node = extract_node(
            """
        import collections
        collections.namedtuple('{}'.format("a"), '')()
        """
        )
        next(node.infer())

    def test_regression_inference_of_self_in_lambda(self) -> None:
        code = """
        class A:
            @b(lambda self: __(self))
            def d(self):
                pass
        """
        node = extract_node(code)
        inferred = next(node.infer())
        assert isinstance(inferred, Instance)
        assert inferred.qname() == ".A"

    def test_inference_context_consideration(self) -> None:
        """https://github.com/PyCQA/astroid/issues/1828"""
        code = """
        class Base:
            def return_type(self):
                return type(self)()
        class A(Base):
            def method(self):
                return self.return_type()
        class B(Base):
            def method(self):
                return self.return_type()
        A().method() #@
        B().method() #@
        """
        node1, node2 = extract_node(code)
        inferred1 = next(node1.infer())
        assert inferred1.qname() == ".A"
        inferred2 = next(node2.infer())
        assert inferred2.qname() == ".B"


class Whatever:
    a = property(lambda x: x, lambda x: x)  # type: ignore[misc]


def test_ancestor_looking_up_redefined_function() -> None:
    code = """
    class Foo:
        def _format(self):
            pass

        def format(self):
            self.format = self._format
            self.format()
    Foo
    """
    node = extract_node(code)
    inferred = next(node.infer())
    ancestor = next(inferred.ancestors())
    _, found = ancestor.lookup("format")
    assert len(found) == 1
    assert isinstance(found[0], nodes.FunctionDef)


def test_crash_in_dunder_inference_prevented() -> None:
    code = """
    class MyClass():
        def fu(self, objects):
            delitem = dict.__delitem__.__get__(self, dict)
            delitem #@
    """
    inferred = next(extract_node(code).infer())
    assert inferred.qname() == "builtins.dict.__delitem__"


def test_regression_crash_classmethod() -> None:
    """Regression test for a crash reported in
    https://github.com/pylint-dev/pylint/issues/4982.
    """
    code = """
    class Base:
        @classmethod
        def get_first_subclass(cls):
            for subclass in cls.__subclasses__():
                return subclass
            return object


    subclass = Base.get_first_subclass()


    class Another(subclass):
        pass
    """
    parse(code)


def test_max_inferred_for_complicated_class_hierarchy() -> None:
    """Regression test for a crash reported in
    https://github.com/pylint-dev/pylint/issues/5679.

    The class hierarchy of 'sqlalchemy' is so intricate that it becomes uninferable with
    the standard max_inferred of 100. We used to crash when this happened.
    """
    # Create module and get relevant nodes
    module = resources.build_file(
        str(resources.RESOURCE_PATH / "max_inferable_limit_for_classes" / "main.py")
    )
    init_attr_node = module.body[-1].body[0].body[0].value.func
    init_object_node = module.body[-1].mro()[-1]["__init__"]
    super_node = next(init_attr_node.expr.infer())

    # Arbitrarily limit the max number of infered nodes per context
    InferenceContext.max_inferred = -1
    context = InferenceContext()

    # Try to infer 'object.__init__' > because of limit is impossible
    for inferred in bases._infer_stmts([init_object_node], context, frame=super):
        assert inferred == Uninferable

    # Reset inference limit
    InferenceContext.max_inferred = 100
    # Check that we don't crash on a previously uninferable node
    assert super_node.getattr("__init__", context=context)[0] == Uninferable


@mock.patch(
    "astroid.nodes.ImportFrom._infer",
    side_effect=RecursionError,
)
def test_recursion_during_inference(mocked) -> None:
    """Check that we don't crash if we hit the recursion limit during inference."""
    node: nodes.Call = _extract_single_node(
        """
    from module import something
    something()
    """
    )
    with pytest.raises(InferenceError) as error:
        next(node.infer())
    assert error.value.message.startswith("RecursionError raised")
