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

"""Tests for scripts/repo_sync_manifest."""

import os
from unittest import mock

from chromite.cbuildbot import manifest_version
from chromite.cbuildbot import repository
from chromite.lib import cros_test_lib
from chromite.scripts import repo_sync_manifest


class RepoSyncManifestTest(cros_test_lib.RunCommandTempDirTestCase):
    """Unit tests for repo_sync_manifest."""

    INT_MANIFEST_URL = (
        "https://chrome-internal-review.googlesource.com/"
        "chromeos/manifest-internal"
    )
    EXT_MANIFEST_URL = "https://chromium.googlesource.com/chromiumos/manifest"

    MV_INT_URL = (
        "https://chrome-internal.googlesource.com/chromeos/manifest-versions"
    )
    MV_EXT_URL = (
        "https://chromium.googlesource.com/chromiumos/manifest-versions"
    )

    def setUp(self) -> None:
        self.repo_dir = os.path.join(self.tempdir, "repo")
        self.repo_url = os.path.join(self.tempdir, ".repo/repo")
        self.preload_src = os.path.join(self.tempdir, "source")
        self.git_cache = os.path.join(self.tempdir, "git_cache")
        self.manifest = os.path.join(self.tempdir, "manifest.xml")
        self.mv_ext = os.path.join(self.tempdir, "mv_ext")
        self.mv_int = os.path.join(self.tempdir, "mv_int")
        self.manifest_url = "manifest.com"

        self.repo_mock = self.PatchObject(
            repository, "RepoRepository", autospec=True
        )

        self.refresh_manifest_mock = self.PatchObject(
            manifest_version, "RefreshManifestCheckout", autospec=True
        )

        self.resolve_buildspec_mock = self.PatchObject(
            manifest_version, "ResolveBuildspec", autospec=True
        )

        self.resolve_version_mock = self.PatchObject(
            manifest_version, "ResolveBuildspecVersion", autospec=True
        )

    def notestHelp(self) -> None:
        with self.assertRaises(SystemExit):
            repo_sync_manifest.main(
                [
                    "--help",
                ]
            )

    def testMinimal(self) -> None:
        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
            ]
        )

        # Ensure manifest_versions is not updated.
        self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.INT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(detach=True, local_manifest=None),
            ],
        )

    def testMinimalExternal(self) -> None:
        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--external",
            ]
        )

        # Ensure manifest_versions is not updated.
        self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.EXT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(detach=True, local_manifest=None),
            ],
        )

    def testMinimalManifestUrl(self) -> None:
        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--manifest-url",
                self.manifest_url,
            ]
        )

        # Ensure manifest_versions is not updated.
        self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.manifest_url,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(detach=True, local_manifest=None),
            ],
        )

    def testBranch(self) -> None:
        repo_sync_manifest.main(
            ["--repo-root", self.repo_dir, "--branch", "branch"]
        )

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.INT_MANIFEST_URL,
                    branch="branch",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(detach=True, local_manifest=None),
            ],
        )

        # Ensure manifest_versions is not updated.
        self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

    def testBuildSpec(self) -> None:
        self.resolve_buildspec_mock.return_value = "resolved_buildspec"

        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--buildspec",
                "test/spec",
                "--manifest-versions-int",
                self.mv_int,
            ]
        )

        # Ensure manifest-versions interactions are correct.
        self.assertEqual(
            self.refresh_manifest_mock.mock_calls,
            [mock.call(self.mv_int, self.MV_INT_URL)],
        )
        self.assertEqual(
            self.resolve_buildspec_mock.mock_calls,
            [mock.call(self.mv_int, "test/spec")],
        )
        self.assertEqual(self.resolve_version_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.INT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(
                    detach=True, local_manifest="resolved_buildspec"
                ),
            ],
        )

    def testBuildSpecExternal(self) -> None:
        self.resolve_buildspec_mock.return_value = "resolved_buildspec"

        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--buildspec",
                "test/spec",
                "--manifest-versions-ext",
                self.mv_ext,
                "--external",
            ]
        )

        # Ensure manifest-versions interactions are correct.
        self.assertEqual(
            self.refresh_manifest_mock.mock_calls,
            [mock.call(self.mv_ext, self.MV_EXT_URL)],
        )
        self.assertEqual(
            self.resolve_buildspec_mock.mock_calls,
            [mock.call(self.mv_ext, "test/spec")],
        )
        self.assertEqual(self.resolve_version_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.EXT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(
                    detach=True, local_manifest="resolved_buildspec"
                ),
            ],
        )

    def testVersion(self) -> None:
        self.resolve_version_mock.return_value = "resolved_buildspec"

        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--version",
                "1.2.3",
                "--manifest-versions-int",
                self.mv_int,
            ]
        )

        # Ensure manifest-versions interactions are correct.
        self.assertEqual(
            self.refresh_manifest_mock.mock_calls,
            [mock.call(self.mv_int, self.MV_INT_URL)],
        )
        self.assertEqual(self.resolve_buildspec_mock.mock_calls, [])
        self.assertEqual(
            self.resolve_version_mock.mock_calls,
            [mock.call(self.mv_int, "1.2.3")],
        )

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.INT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(
                    detach=True, local_manifest="resolved_buildspec"
                ),
            ],
        )

    def testVersionExternal(self) -> None:
        self.resolve_version_mock.return_value = "resolved_buildspec"

        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--version",
                "1.2.3",
                "--manifest-versions-ext",
                self.mv_ext,
                "--external",
            ]
        )

        # Ensure manifest-versions interactions are correct.
        self.assertEqual(
            self.refresh_manifest_mock.mock_calls,
            [mock.call(self.mv_ext, self.MV_EXT_URL)],
        )
        self.assertEqual(self.resolve_buildspec_mock.mock_calls, [])
        self.assertEqual(
            self.resolve_version_mock.mock_calls,
            [mock.call(self.mv_ext, "1.2.3")],
        )

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.EXT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(
                    detach=True, local_manifest="resolved_buildspec"
                ),
            ],
        )

    def testBuildSpecNoManifestVersions(self) -> None:
        with self.assertRaises(AssertionError):
            repo_sync_manifest.main(
                [
                    "--repo-root",
                    self.repo_dir,
                    "--buildspec",
                    "test/spec",
                ]
            )

        with self.assertRaises(AssertionError):
            repo_sync_manifest.main(
                [
                    "--repo-root",
                    self.repo_dir,
                    "--buildspec",
                    "test/spec",
                    "--external",
                ]
            )

    def testLocalManifest(self) -> None:
        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--manifest-file",
                self.manifest,
            ]
        )

        # Ensure manifest_versions is not updated.
        self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.INT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups=None,
                ),
                mock.call().Sync(detach=True, local_manifest=self.manifest),
            ],
        )

    def testGroups(self) -> None:
        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--manifest-file",
                self.manifest,
                "--groups",
                "all",
            ]
        )

        # Ensure manifest_versions is not updated.
        self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.INT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=None,
                    repo_url=None,
                    groups="all",
                ),
                mock.call().Sync(detach=True, local_manifest=self.manifest),
            ],
        )

    def testOptimizations(self) -> None:
        repo_sync_manifest.main(
            [
                "--repo-root",
                self.repo_dir,
                "--copy-repo",
                self.preload_src,
                "--git-cache",
                self.git_cache,
                "--repo-url",
                self.repo_url,
            ]
        )

        # Ensure manifest_versions is not updated.
        self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

        # Ensure RepoRepository created and Sync'd as expected.
        self.assertEqual(
            self.repo_mock.mock_calls,
            [
                mock.call(
                    directory=self.repo_dir,
                    manifest_repo_url=self.INT_MANIFEST_URL,
                    branch="master",
                    git_cache_dir=self.git_cache,
                    repo_url=self.repo_url,
                    groups=None,
                ),
                mock.call().PreLoad(self.preload_src),
                mock.call().Sync(detach=True, local_manifest=None),
            ],
        )
