# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt

import os
import re
import sys
from pathlib import Path

import astroid

from pylint.checkers import variables
from pylint.interfaces import HIGH
from pylint.testutils import CheckerTestCase, MessageTest, linter, set_config
from pylint.testutils.reporter_for_tests import GenericTestReporter

REGR_DATA_DIR = str(Path(__file__).parent / ".." / "regrtest_data")


class TestVariablesChecker(CheckerTestCase):
    CHECKER_CLASS = variables.VariablesChecker

    def test_all_elements_without_parent(self) -> None:
        node = astroid.extract_node("__all__ = []")
        node.value.elts.append(astroid.Const("test"))
        root = node.root()
        with self.assertNoMessages():
            self.checker.visit_module(root)
            self.checker.leave_module(root)


class TestVariablesCheckerWithTearDown(CheckerTestCase):
    CHECKER_CLASS = variables.VariablesChecker

    def setup_method(self) -> None:
        super().setup_method()
        self._to_consume_backup = self.checker._to_consume
        self.checker._to_consume = []

    def teardown_method(self) -> None:
        self.checker._to_consume = self._to_consume_backup

    @set_config(callbacks=("callback_", "_callback"))
    def test_custom_callback_string(self) -> None:
        """Test the --callbacks option works."""
        node = astroid.extract_node(
            """
        def callback_one(abc):
             ''' should not emit unused-argument. '''
        """
        )
        with self.assertNoMessages():
            self.checker.visit_functiondef(node)
            self.checker.leave_functiondef(node)

        node = astroid.extract_node(
            """
        def two_callback(abc, defg):
             ''' should not emit unused-argument. '''
        """
        )
        with self.assertNoMessages():
            self.checker.visit_functiondef(node)
            self.checker.leave_functiondef(node)

        node = astroid.extract_node(
            """
        def normal_func(abc):
             ''' should emit unused-argument. '''
        """
        )
        with self.assertAddsMessages(
            MessageTest(
                "unused-argument",
                node=node["abc"],
                args="abc",
                confidence=HIGH,
                line=2,
                col_offset=16,
                end_line=2,
                end_col_offset=19,
            )
        ):
            self.checker.visit_functiondef(node)
            self.checker.leave_functiondef(node)

        node = astroid.extract_node(
            """
        def cb_func(abc):
             ''' Previous callbacks are overridden. '''
        """
        )
        with self.assertAddsMessages(
            MessageTest(
                "unused-argument",
                node=node["abc"],
                args="abc",
                confidence=HIGH,
                line=2,
                col_offset=12,
                end_line=2,
                end_col_offset=15,
            )
        ):
            self.checker.visit_functiondef(node)
            self.checker.leave_functiondef(node)

    @set_config(redefining_builtins_modules=("os",))
    def test_redefined_builtin_modname_not_ignored(self) -> None:
        node = astroid.parse(
            """
        from future.builtins import open
        """
        )
        with self.assertAddsMessages(
            MessageTest(
                "redefined-builtin",
                node=node.body[0],
                args="open",
                line=2,
                col_offset=0,
                end_line=2,
                end_col_offset=32,
            )
        ):
            self.checker.visit_module(node)

    @set_config(redefining_builtins_modules=("os",))
    def test_redefined_builtin_in_function(self) -> None:
        node = astroid.extract_node(
            """
        def test():
            from os import open
        """
        )
        with self.assertNoMessages():
            self.checker.visit_module(node.root())
            self.checker.visit_functiondef(node)

    def test_import_as_underscore(self) -> None:
        node = astroid.parse(
            """
        import math as _
        """
        )
        with self.assertNoMessages():
            self.walk(node)

    def test_lambda_in_classdef(self) -> None:
        # Make sure lambda doesn't raises
        # Undefined-method in class def

        # Issue 1824
        # https://github.com/pylint-dev/pylint/issues/1824
        node = astroid.parse(
            """
        class MyObject(object):
            method1 = lambda func: func()
            method2 = lambda function: function()
        """
        )
        with self.assertNoMessages():
            self.walk(node)

    def test_nested_lambda(self) -> None:
        """Make sure variables from parent lambdas
        aren't noted as undefined.

        https://github.com/pylint-dev/pylint/issues/760
        """
        node = astroid.parse(
            """
        lambda x: lambda: x + 1
        """
        )
        with self.assertNoMessages():
            self.walk(node)

    @set_config(ignored_argument_names=re.compile("arg"))
    def test_ignored_argument_names_no_message(self) -> None:
        """Make sure is_ignored_argument_names properly ignores
        function arguments.
        """
        node = astroid.parse(
            """
        def fooby(arg):
            pass
        """
        )
        with self.assertNoMessages():
            self.walk(node)

    @set_config(ignored_argument_names=re.compile("args|kwargs"))
    def test_ignored_argument_names_starred_args(self) -> None:
        node = astroid.parse(
            """
        def fooby(*args, **kwargs):
            pass
        """
        )
        with self.assertNoMessages():
            self.walk(node)


class TestMissingSubmodule(CheckerTestCase):
    CHECKER_CLASS = variables.VariablesChecker

    @staticmethod
    def test_package_all() -> None:
        sys.path.insert(0, REGR_DATA_DIR)
        try:
            linter.check([os.path.join(REGR_DATA_DIR, "package_all")])
            assert isinstance(linter.reporter, GenericTestReporter)
            got = linter.reporter.finalize().strip()
            assert got == "E:  3: Undefined variable name 'missing' in __all__"
        finally:
            sys.path.pop(0)
