#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import tempfile
import unittest

from pyspark.testing.utils import (
    PySparkBaseTestCase,
    grimp_requirement_message,
    have_grimp,
)

# A test module and modules it does / does not import (transitively). These relationships are
# stable parts of the pyspark import graph.
_TEST_MODULE = "pyspark.sql.tests.test_functions"
_RELEVANT_FILE = "python/pyspark/sql/functions/builtin.py"  # imported by _TEST_MODULE
_IRRELEVANT_FILE = "python/pyspark/ml/classification.py"  # not imported by _TEST_MODULE


@unittest.skipIf(not have_grimp, grimp_requirement_message)
class ChangedFilesSelectionTests(unittest.TestCase):
    """Tests for the "smart" test selection driven by PYSPARK_CHANGED_FILES.

    ``PySparkBaseTestCase.skip_if_changed_files_irrelevant`` skips a test class when none of the
    changed files' modules are reachable from the test's own module in the pyspark import graph.
    These exercise that logic directly against real pyspark modules with known relationships.
    """

    def setUp(self):
        # The relevance check is memoized with functools.cache; clear it so each case starts fresh.
        PySparkBaseTestCase._is_module_relevant_to_changed_files.cache_clear()

    def _is_relevant(self, module, files):
        with tempfile.NamedTemporaryFile("w") as f:
            f.write("\n".join(files))
            f.flush()
            return PySparkBaseTestCase._is_module_relevant_to_changed_files(module, f.name)

    def test_relevance(self):
        own_file = "python/" + _TEST_MODULE.replace(".", os.path.sep) + ".py"
        cases = [
            ("imported module is relevant", [_RELEVANT_FILE], True),
            ("unimported module is irrelevant", [_IRRELEVANT_FILE], False),
            ("relevant among irrelevant is relevant", [_IRRELEVANT_FILE, _RELEVANT_FILE], True),
            ("the test's own file is relevant via the self-module short circuit", [own_file], True),
            (
                "non-pyspark files are conservatively relevant",
                ["sql/core/src/main/scala/Foo.scala"],
                True,
            ),
            (
                "package __init__ with no graph node is conservatively relevant",
                ["python/pyspark/sql/__init__.py"],
                True,
            ),
        ]
        for desc, files, expected in cases:
            with self.subTest(desc):
                self.assertEqual(self._is_relevant(_TEST_MODULE, files), expected)

    def test_skip_if_changed_files_irrelevant(self):
        class _Dummy(PySparkBaseTestCase):
            pass

        _Dummy.__module__ = _TEST_MODULE

        # Irrelevant changes raise SkipTest.
        with tempfile.NamedTemporaryFile("w") as f:
            f.write(_IRRELEVANT_FILE)
            f.flush()
            with self.assertRaises(unittest.SkipTest):
                _Dummy.skip_if_changed_files_irrelevant(f.name)

        # Relevant changes do not.
        with tempfile.NamedTemporaryFile("w") as f:
            f.write(_RELEVANT_FILE)
            f.flush()
            _Dummy.skip_if_changed_files_irrelevant(f.name)


if __name__ == "__main__":
    from pyspark.testing import main

    main()
