# Copyright (C) 2026 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.

"""Unittests for the subcmds/gc.py module."""

from pathlib import Path
import unittest
from unittest import mock

import manifest_xml
from subcmds import gc


class GcCommand(unittest.TestCase):
    """Tests for gc command."""

    def setUp(self):
        self.cmd = gc.Gc(manifest=mock.MagicMock())
        self.opt, self.args = self.cmd.OptionParser.parse_args([])
        self.opt.this_manifest_only = False
        self.opt.repack = False

        self.mock_get_projects = mock.patch.object(
            self.cmd, "GetProjects"
        ).start()

        self.mock_delete = mock.patch.object(
            self.cmd, "delete_unused_projects", return_value=0
        ).start()

        self.mock_repack = mock.patch.object(
            self.cmd, "repack_projects", return_value=0
        ).start()

    def tearDown(self):
        mock.patch.stopall()

    def test_gc_no_args(self):
        """Test gc without specific projects."""
        self.mock_get_projects.return_value = ["all_projects"]

        self.cmd.Execute(self.opt, [])

        self.mock_get_projects.assert_called_once_with([], all_manifests=True)
        self.mock_delete.assert_called_once_with(["all_projects"], self.opt)
        self.mock_repack.assert_not_called()

    def test_gc_with_args(self):
        """Test gc with specific projects uses all_projects for delete."""
        self.mock_get_projects.side_effect = [["projA"], ["all_projects"]]
        self.opt.repack = True

        self.cmd.Execute(self.opt, ["projA"])

        self.mock_get_projects.assert_has_calls(
            [
                mock.call(["projA"], all_manifests=True),
                mock.call([], all_manifests=True),
            ]
        )

        self.mock_delete.assert_called_once_with(["all_projects"], self.opt)
        self.mock_repack.assert_called_once_with(["projA"], self.opt)

    def test_gc_exit_on_delete_failure(self):
        """Test gc exits if delete_unused_projects fails."""
        self.mock_get_projects.return_value = ["all_projects"]
        self.mock_delete.return_value = 1
        self.opt.repack = True

        ret = self.cmd.Execute(self.opt, [])
        self.assertEqual(ret, 1)
        self.mock_repack.assert_not_called()


def test_gc_keep_manifest_projects(tmp_path: Path) -> None:
    """Keep inactive projects that are still in the manifest."""
    repodir = tmp_path / ".repo"
    manifest_dir = repodir / "manifests"
    manifest_file = repodir / manifest_xml.MANIFEST_FILE_NAME

    repodir.mkdir()
    manifest_dir.mkdir()

    manifest_gitdir = repodir / "manifests.git"
    manifest_gitdir.mkdir()
    (manifest_gitdir / "config").write_text(
        """[remote "origin"]
        url = https://localhost:0/manifest
        """,
        encoding="utf-8",
    )

    manifest_file.write_text(
        """\
        <manifest>
        <remote name="origin" fetch="http://localhost" />
        <default remote="origin" revision="refs/heads/main" />
        <project name="included" groups="active-group" />
        <project name="excluded" groups="other-group" />
        </manifest>
        """,
        encoding="utf-8",
    )

    manifest = manifest_xml.XmlManifest(str(repodir), str(manifest_file))
    manifest.manifestProject.config.SetString(
        "manifest.groups",
        "active-group",
    )

    projects = {project.name: project for project in manifest.projects}
    included = projects["included"]
    excluded = projects["excluded"]

    Path(included.gitdir).mkdir(parents=True)
    Path(included.objdir).mkdir(parents=True)

    # Simulate an inactive project with only its object cache left.
    Path(excluded.objdir).mkdir(parents=True)
    assert not excluded.Exists

    orphan_gitdir = repodir / "projects" / "orphan.git"
    orphan_objdir = repodir / "project-objects" / "orphan.git"
    orphan_gitdir.mkdir()
    orphan_objdir.mkdir()

    cmd = gc.Gc(repodir=str(repodir), manifest=manifest)

    opt, args = cmd.OptionParser.parse_args(
        ["--yes", "--keep-manifest-projects"]
    )
    opt.quiet = True

    selected_projects = cmd.GetProjects([], all_manifests=True)
    assert included in selected_projects
    assert excluded not in selected_projects

    cmd.Execute(opt, args)

    assert included.Exists
    assert Path(excluded.objdir).exists()
    assert not orphan_gitdir.exists()
    assert not orphan_objdir.exists()


def test_gc_keep_manifest_projects_preserves_repack_targets() -> None:
    """Keep manifest projects without expanding repack targets."""
    cmd = gc.Gc()
    opt, _ = cmd.OptionParser.parse_args(
        ["--keep-manifest-projects", "--repack"]
    )
    opt.this_manifest_only = False

    with mock.patch.object(
        cmd,
        "GetProjects",
        side_effect=[["projA"], ["manifest_projects"]],
    ) as get_projects, mock.patch.object(
        cmd, "delete_unused_projects", return_value=0
    ) as delete, mock.patch.object(
        cmd, "repack_projects", return_value=0
    ) as repack:
        cmd.Execute(opt, ["projA"])

    get_projects.assert_has_calls(
        [
            mock.call(["projA"], all_manifests=True),
            mock.call(
                [],
                groups="all",
                missing_ok=True,
                all_manifests=True,
            ),
        ]
    )
    delete.assert_called_once_with(["manifest_projects"], opt)
    repack.assert_called_once_with(["projA"], opt)
