#
# Copyright (C) 2023 The Android Open Source Project
#
# Licensed 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.
#
"""Tests for manifest.py."""
import textwrap
from pathlib import Path

import pytest

from manifest import Manifest, ManifestParser, find_manifest_xml_for_tree


class TestFindManifestXmlForTree:
    """Tests for find_manifest_xml_for_tree."""

    def test_repo_tree(self, repo_tree: Path) -> None:
        """Tests that the correct manifest file is found in a repo tree."""
        manifest_dir = Path(repo_tree / ".repo/manifests")
        manifest_dir.mkdir()
        manifest_path = manifest_dir / "default.xml"
        manifest_path.touch()
        assert find_manifest_xml_for_tree(repo_tree) == manifest_path

    def test_no_manifest(self, tmp_path: Path) -> None:
        """Tests that an error is raised when no manifest is found."""
        with pytest.raises(FileNotFoundError):
            find_manifest_xml_for_tree(tmp_path)


class TestManifestParser:
    """Tests for ManifestParser."""

    def test_manifest_default_missing(self, tmp_path: Path) -> None:
        """Tests that an error is raised when the default node is missing."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <project path="external/project" revision="master" />
                </manifest>
                """
            )
        )
        with pytest.raises(RuntimeError):
            ManifestParser(manifest_path).parse()

    def test_project_name_missing(self, tmp_path: Path) -> None:
        """Tests that an error is raised when neither name nor path is defined for a project."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default revision="main" remote="testremote" />

                    <project />
                </manifest>
                """
            )
        )
        with pytest.raises(RuntimeError):
            ManifestParser(manifest_path).parse()

    def test_multiple_manifest_default(self, tmp_path: Path) -> None:
        """Tests that an error is raised when there is more than one default node."""
        manifest = tmp_path / "manifest.xml"
        manifest.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default revision="main" remote="testremote" />
                    <default revision="main" remote="testremote" />

                    <project path="external/project" revision="master" />
                </manifest>
                """
            )
        )
        with pytest.raises(RuntimeError):
            ManifestParser(manifest).parse()

    def test_manifest_remote(self, tmp_path: Path) -> None:
        """Tests that the correct remote name of the manifest is found."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <remote name="testremote" />
                    <default revision="main" remote="testremote" />

                    <project path="external/project" remote="origin" />
                </manifest>
                """
            )
        )
        manifest = ManifestParser(manifest_path).parse()
        assert manifest.remote == "testremote"

    def test_project_remote_default(self, tmp_path: Path) -> None:
        """Tests that the default remote is used when not defined by the project."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <remote name="testremote" />
                    <default revision="main" remote="testremote" />

                    <project path="external/project" />
                </manifest>
                """
            )
        )
        manifest = ManifestParser(manifest_path).parse()
        assert manifest.project_with_path("external/project").remote == "testremote"

    def test_project_revision_default(self, tmp_path: Path) -> None:
        """Tests that the default revision is used when not defined by the project."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default revision="main" remote="testremote" />

                    <project path="external/project" />
                </manifest>
                """
            )
        )
        manifest = ManifestParser(manifest_path).parse()
        assert manifest.project_with_path("external/project").revision == "main"

    def test_project_path_default(self, tmp_path: Path) -> None:
        """Tests that the default path is used when not defined by the project."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default revision="main" remote="testremote" />

                    <project name="external/project" />
                </manifest>
                """
            )
        )
        manifest = ManifestParser(manifest_path).parse()
        assert manifest.project_with_path("external/project") is not None

    def test_project_remote_explicit(self, tmp_path: Path) -> None:
        """Tests that the project remote is used when defined."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default revision="main" remote="testremote" />

                    <project path="external/project" remote="origin" />
                </manifest>
                """
            )
        )
        manifest = ManifestParser(manifest_path).parse()
        assert manifest.project_with_path("external/project").remote == "origin"

    def test_project_revision_explicit(self, tmp_path: Path) -> None:
        """Tests that the project revision is used when defined."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default revision="main" remote="testremote" />

                    <project path="external/project" revision="master" />
                </manifest>
                """
            )
        )
        manifest = ManifestParser(manifest_path).parse()
        assert manifest.project_with_path("external/project").revision == "master"

    def test_project_path_explicit(self, tmp_path: Path) -> None:
        """Tests that the project path is used when defined."""
        manifest_path = tmp_path / "manifest.xml"
        manifest_path.write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default revision="main" remote="testremote" />

                    <project name="external/project" path="other/path" />
                </manifest>
                """
            )
        )
        manifest = ManifestParser(manifest_path).parse()
        assert manifest.project_with_path("other/path") is not None


class TestManifest:
    """Tests for Manifest."""

    def test_for_tree(self, repo_tree: Path) -> None:
        """Tests the Manifest.for_tree constructor."""
        manifest_dir = Path(repo_tree / ".repo/manifests")
        manifest_dir.mkdir()
        (manifest_dir / "default.xml").write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default remote="testremote" revision="main" />

                    <project path="external/a" />
                    <project path="external/b" />
                    <project path="external/c" />
                </manifest>
                """
            )
        )
        manifest = Manifest.for_tree(repo_tree)
        assert len(manifest.projects_by_path) == 3

    def test_project_with_path(self, repo_tree: Path) -> None:
        """Tests that Manifest.project_with_path returns the correct project."""
        manifest_dir = Path(repo_tree / ".repo/manifests")
        manifest_dir.mkdir()
        (manifest_dir / "default.xml").write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default remote="testremote" revision="main" />

                    <project path="external/a" />
                    <project path="external/b" />
                    <project path="external/c" />
                </manifest>
                """
            )
        )
        manifest = Manifest.for_tree(repo_tree)
        assert manifest.project_with_path("external/b").path == "external/b"

    def test_project_with_path_missing(self, repo_tree: Path) -> None:
        """Tests that Manifest.project_with_path raises an error when not found."""
        manifest_dir = Path(repo_tree / ".repo/manifests")
        manifest_dir.mkdir()
        (manifest_dir / "default.xml").write_text(
            textwrap.dedent(
                """\
                <?xml version="1.0" encoding="UTF-8"?>
                <manifest>
                    <default remote="testremote" revision="main" />

                    <project path="external/a" />
                    <project path="external/b" />
                    <project path="external/c" />
                </manifest>
                """
            )
        )
        manifest = Manifest.for_tree(repo_tree)
        with pytest.raises(KeyError):
            manifest.project_with_path("external/d")
