# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for the dependency.py module."""

import pytest

from chromite.lib import build_target_lib
from chromite.lib import cros_test_lib
from chromite.lib import dependency_graph
from chromite.lib import dependency_lib
from chromite.lib import depgraph
from chromite.lib.parser import package_info
from chromite.service import dependency


pytestmark = cros_test_lib.pytestmark_inside_only


class DependencyTests(cros_test_lib.MockTestCase):
    """General unittests for dependency module."""

    def _build_sysroot_depgraph(self, sysroot="/build/target"):
        """Build a DependencyGraph to test against."""

        virtual = package_info.parse("virtual/target-foo-1.2.3")
        dep1 = package_info.parse("cat/dep-1.0.0-r1")
        dep2 = package_info.parse("cat/dep-2.0.0-r1")
        virtual_dep = package_info.parse("virtual/depdep-1.0")
        depdep = package_info.parse("cat/depdep-2.0.1-r5")

        virtual_node = dependency_graph.PackageNode(
            virtual, sysroot, src_paths=["/virtual/foo"]
        )
        dep1_node = dependency_graph.PackageNode(
            dep1, sysroot, src_paths=["/cat/dep/one"]
        )
        dep2_node = dependency_graph.PackageNode(
            dep2, sysroot, src_paths=["/cat/dep/two"]
        )
        virtual_dep_node = dependency_graph.PackageNode(
            virtual_dep, sysroot, src_paths=["/virtual/depdep"]
        )
        depdep_node = dependency_graph.PackageNode(
            depdep, sysroot, src_paths=["/cat/depdep", "/other/depdep"]
        )

        virtual_node.add_dependency(dep1_node)
        virtual_node.add_dependency(dep2_node)
        dep1_node.add_dependency(virtual_dep_node)
        virtual_dep_node.add_dependency(depdep_node)

        nodes = (
            virtual_node,
            dep1_node,
            dep2_node,
            virtual_dep_node,
            depdep_node,
        )

        return dependency_graph.DependencyGraph(nodes, sysroot, [virtual])

    def setUp(self) -> None:
        self.json_deps = {
            "target_board": "deathstar",
            "sysroot_path": "/build/deathstar",
            "package_deps": {
                "commander/darthvader-1.49.3.3": {
                    "action": "merge",
                    "category": "commander",
                    "cpes": [],
                    "deps": ["troop/clone", "troop/robot"],
                    "rev_deps": [],
                    "full_name": "commander/darthvader-1.49.3.3",
                    "name": "darthvader",
                    "version": "1.49.3.3",
                },
                "troop/clone-1.2.3": {
                    "action": "merge",
                    "category": "troop",
                    "cpes": [],
                    "deps": ["equipment/jetpack"],
                    "rev_deps": ["commander/darthvader"],
                    "full_name": "troop/clone-1.2.3",
                    "name": "clone",
                    "version": "1.2.3",
                },
                "troop/robot-2.3.4": {
                    "action": "merge",
                    "category": "troop",
                    "cpes": [],
                    "deps": [],
                    "rev_deps": ["commander/darthvader"],
                    "full_name": "troop/robot-2.3.4",
                    "name": "robot",
                    "version": "2.3.4",
                },
                "equipment/jetpack-3.4.5": {
                    "action": "merge",
                    "category": "equipment",
                    "cpes": [],
                    "deps": [],
                    "rev_deps": ["commander/darthvader"],
                    "full_name": "equipment/jetpack-3.4.5",
                    "name": "jetpack",
                    "version": "3.4.5",
                },
            },
            "source_path_mapping": {
                "commander/darthvader-1.49.3.3": ["/control/room"],
                "troop/clone-1.2.3": ["/bunker"],
                "troop/robot-2.3.4": ["/factory"],
                "equipment/jetpack-3.4.5": ["/factory"],
            },
        }

    def testDeterminePackageRelevanceNotRelevant(self) -> None:
        """Test determine_package_relevance with no matching paths."""
        src_paths = ["foo/bar/baz", "foo/bar/b", "foo/bar", "bar/foo"]
        dep_src_paths = ["foo/bar/ba"]
        self.assertFalse(
            dependency.determine_package_relevance(dep_src_paths, src_paths)
        )

    def testDeterminePackageRelevanceExactMatch(self) -> None:
        """Test determine_package_relevance given an exact match."""
        src_paths = ["foo/bar/baz"]
        dep_src_paths = ["foo/bar/baz"]
        self.assertTrue(
            dependency.determine_package_relevance(dep_src_paths, src_paths)
        )

    def testDeterminePackageRelevanceDirectoryMatch(self) -> None:
        """Test determine_package_relevance given a directory match."""
        src_paths = ["foo/bar/baz"]
        dep_src_paths = ["foo/bar"]
        self.assertTrue(
            dependency.determine_package_relevance(dep_src_paths, src_paths)
        )

    def testGetDependenciesWithDefaultArgs(self) -> None:
        """Test GetDependencies using the default args."""
        self.PatchObject(
            depgraph,
            "get_sysroot_dependency_graph",
            return_value=(self._build_sysroot_depgraph()),
        )
        sysroot_path = "/build/target"
        actual_deps = dependency.GetDependencies(sysroot_path)
        dep1 = package_info.parse("cat/dep-1.0.0-r1")
        dep2 = package_info.parse("cat/dep-2.0.0-r1")
        virtual = package_info.parse("virtual/target-foo-1.2.3")
        virtual_depdep = package_info.parse("virtual/depdep-1.0")
        depdep = package_info.parse("cat/depdep-2.0.1-r5")

        expected_deps = [dep1, dep2, virtual, virtual_depdep, depdep]
        self.assertEqual(set(expected_deps), set(actual_deps))

    def testGetDependenciesWithSdkSysroot(self) -> None:
        """Test GetDependencies with the SDK depgraph."""
        self.PatchObject(
            depgraph,
            "get_sdk_dependency_graph",
            return_value=(
                self._build_sysroot_depgraph(
                    sysroot=build_target_lib.get_sdk_sysroot_path()
                )
            ),
        )
        sysroot_path = build_target_lib.get_sdk_sysroot_path()
        actual_deps = dependency.GetDependencies(sysroot_path)
        dep1 = package_info.parse("cat/dep-1.0.0-r1")
        dep2 = package_info.parse("cat/dep-2.0.0-r1")
        virtual = package_info.parse("virtual/target-foo-1.2.3")
        virtual_depdep = package_info.parse("virtual/depdep-1.0")
        depdep = package_info.parse("cat/depdep-2.0.1-r5")

        expected_deps = [dep1, dep2, virtual, virtual_depdep, depdep]
        self.assertEqual(set(expected_deps), set(actual_deps))

    def testGetDependenciesWithSrcPaths(self) -> None:
        """Test GetDependencies given a list of paths."""
        self.PatchObject(
            depgraph,
            "get_sysroot_dependency_graph",
            return_value=(self._build_sysroot_depgraph()),
        )
        sysroot_path = "/build/target"
        src_paths = ["/cat/dep/one"]
        actual_deps = dependency.GetDependencies(sysroot_path, src_paths)
        dep = package_info.parse("cat/dep-1.0.0-r1")
        self.assertCountEqual([dep], actual_deps)

    def testGetDependenciesWithSrcPathsAndReverseDeps(self) -> None:
        """Test GetDependencies given a list of paths."""
        self.PatchObject(
            depgraph,
            "get_sysroot_dependency_graph",
            return_value=(self._build_sysroot_depgraph()),
        )
        sysroot_path = "/build/target"
        src_paths = ["/cat/dep/one"]
        actual_deps = dependency.GetDependencies(
            sysroot_path, src_paths, include_rev_dependencies=True
        )

        revdep = package_info.parse("virtual/target-foo-1.2.3")
        dep = package_info.parse("cat/dep-1.0.0-r1")
        self.assertEqual({dep, revdep}, actual_deps)

    def testGetDependenciesAffectedPackagesVirtualRedirect(self) -> None:
        """Test include_affected_pkgs traverses redirection virtuals."""
        self.PatchObject(
            depgraph,
            "get_sysroot_dependency_graph",
            return_value=(self._build_sysroot_depgraph()),
        )
        sysroot_path = "/build/target"
        src_paths = ["/cat/depdep"]

        actual_deps = dependency.GetDependencies(
            sysroot_path,
            src_paths,
            include_affected_pkgs=True,
        )

        expected = {
            package_info.parse("cat/depdep-2.0.1-r5"),
            package_info.parse("virtual/depdep-1.0"),
            package_info.parse("cat/dep-1.0.0-r1"),
        }

        self.assertEqual(expected, actual_deps)

    def testGetDependenciesAffectedPackagesVirtualParent(self) -> None:
        """Test include_affected_pkgs does not include virtual parents."""
        self.PatchObject(
            depgraph,
            "get_sysroot_dependency_graph",
            return_value=(self._build_sysroot_depgraph()),
        )
        sysroot_path = "/build/target"
        src_paths = ["/cat/dep/one"]
        actual_deps = dependency.GetDependencies(
            sysroot_path,
            src_paths,
            include_affected_pkgs=True,
        )

        dep = package_info.parse("cat/dep-1.0.0-r1")
        self.assertEqual({dep}, actual_deps)


def test_generate_source_path_mapping_sdk(monkeypatch) -> None:
    """Test GenerateSourcePathMapping sdk argument."""

    def gspm_patch(_packages, sysroot_path, board, *_args, **_kwargs) -> None:
        assert sysroot_path == "/"
        assert board is None

    monkeypatch.setattr(dependency_lib, "get_source_path_mapping", gspm_patch)
    dependency.GenerateSourcePathMapping(["cat/pkg"], sdk=True)


def test_generate_source_path_mapping_sdk_only() -> None:
    """Test GenerateSourcePathMapping argument handling when setting sdk."""
    # Board.
    with pytest.raises(AssertionError):
        dependency.GenerateSourcePathMapping(
            ["cat/pkg"], sdk=True, board="board"
        )
    # Sysroot.
    with pytest.raises(AssertionError):
        dependency.GenerateSourcePathMapping(
            ["cat/pkg"], sdk=True, sysroot_path="/build/board"
        )
    # Board and sysroot.
    with pytest.raises(AssertionError):
        dependency.GenerateSourcePathMapping(
            ["cat/pkg"], sdk=True, board="board", sysroot_path="/build/board"
        )


def test_generate_source_path_mapping_sdk_sysroot(monkeypatch) -> None:
    """Test GenerateSourcePathMapping with the sdk's sysroot."""

    def gspm_patch(_packages, sysroot_path, board, *_args, **_kwargs) -> None:
        assert sysroot_path == "/"
        assert board is None

    monkeypatch.setattr(dependency_lib, "get_source_path_mapping", gspm_patch)
    dependency.GenerateSourcePathMapping(["cat/pkg"], sysroot_path="/")


def test_generate_source_path_mapping_board_sysroot(monkeypatch) -> None:
    """Test GenerateSourcePathMapping with a board's sysroot."""

    def gspm_patch(_packages, sysroot_path, board, *_args, **_kwargs) -> None:
        assert sysroot_path == "/build/board"
        assert board == "board"

    monkeypatch.setattr(dependency_lib, "get_source_path_mapping", gspm_patch)
    dependency.GenerateSourcePathMapping(
        ["cat/pkg"], sysroot_path="/build/board"
    )


def test_generate_source_path_mapping_board(monkeypatch) -> None:
    """Test GenerateSourcePathMapping with a board."""

    def gspm_patch(_packages, sysroot_path, board, *_args, **_kwargs) -> None:
        assert sysroot_path == "/build/board"
        assert board == "board"

    monkeypatch.setattr(dependency_lib, "get_source_path_mapping", gspm_patch)
    dependency.GenerateSourcePathMapping(["cat/pkg"], board="board")


def test_generate_source_path_mapping_board_and_sysroot(monkeypatch) -> None:
    """Test GenerateSourcePathMapping with a board and custom sysroot."""

    def gspm_patch(_packages, sysroot_path, board, *_args, **_kwargs) -> None:
        assert sysroot_path == "/some/sysroot"
        assert board == "board"

    monkeypatch.setattr(dependency_lib, "get_source_path_mapping", gspm_patch)
    dependency.GenerateSourcePathMapping(
        ["cat/pkg"], board="board", sysroot_path="/some/sysroot"
    )
