#!/usr/bin/env fuchsia-vendored-python

# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for cipd_utils.py."""

# pylint: disable=missing-class-docstring
# pylint: disable=missing-function-docstring

import os
import subprocess
import tempfile
import textwrap
from typing import List
import unittest
from unittest import mock

import cipd_utils


def get_run_commands(mock_run) -> List[List[str]]:
    """Extracts just the subprocess command list from a mock.

    This just helps reduce boilerplate in the common case where we just
    want to make sure we called the right subprocess command.

    For example, given these calls:
      subprocess.run(["echo", "foo"], check=True, capture_output=True)
      subprocess.run(["echo", "bar"], check=False)
    This would return:
      [["echo", "foo"], ["echo", "bar"]].
    """
    return [mock_args[0] for mock_args, _ in mock_run.call_args_list]


class GitTests(unittest.TestCase):

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_git_command(self, mock_run):
        git = cipd_utils.Git("path/to/repo/")

        git.git(["foo", "bar"])

        mock_run.assert_called_once_with(
            ["git", "-C", "path/to/repo/", "foo", "bar"],
            check=True,
            text=True,
            capture_output=True)

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_changelog(self, mock_run):
        git = cipd_utils.Git("path/")
        mock_run.return_value = subprocess.CompletedProcess(None, 0, "fake log")

        result = git.changelog("start_revision", "end_revision")

        self.assertEqual(
            get_run_commands(mock_run), [
                [
                    "git", "-C", "path/", "log", "--oneline",
                    "start_revision..end_revision"
                ]
            ])
        self.assertEqual(result, "fake log")

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_changelog_no_start(self, mock_run):
        git = cipd_utils.Git("path/")
        mock_run.return_value = subprocess.CompletedProcess(None, 0, "fake log")

        result = git.changelog(None, "end_revision")

        self.assertEqual(
            get_run_commands(mock_run),
            [["git", "-C", "path/", "log", "--oneline", "end_revision"]])
        self.assertEqual(result, "fake log")


# Based off `repo info --local-only` output for repo version v2.21.
_FAKE_REPO_INFO = textwrap.dedent(
    """\
    Manifest branch: main
    Manifest merge branch: refs/heads/main
    Manifest groups: all,-notdefault
    ----------------------------
    Project: foo
    Mount path: /repo/root/foo
    Current revision: foo_revision
    Manifest revision: main
    Local Branches: 0
    ----------------------------
    Project: bar/baz
    Mount path: /repo/root/baz
    Current revision: baz_revision
    Manifest revision: baz_revision
    Local Branches: 1 [baz_local_branch]
    ----------------------------
    """)


class RepoTests(unittest.TestCase):

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_repo_init(self, mock_run):
        mock_run.return_value = subprocess.CompletedProcess(
            None, 0, _FAKE_REPO_INFO)

        repo = cipd_utils.Repo("/repo/root")

        self.assertEqual(
            get_run_commands(mock_run), [["repo", "info", "--local-only"]])
        self.assertEqual(len(repo.git_repos), 2)
        self.assertEqual(repo.git_repos["foo"].repo_path, "/repo/root/foo")
        self.assertEqual(repo.git_repos["bar/baz"].repo_path, "/repo/root/baz")

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_repo_init_spec_no_alias(self, mock_run):
        mock_run.return_value = subprocess.CompletedProcess(
            None, 0, _FAKE_REPO_INFO)

        repo = cipd_utils.Repo("/repo/root", spec={"foo": None})

        self.assertEqual(len(repo.git_repos), 1)
        self.assertEqual(repo.git_repos["foo"].repo_path, "/repo/root/foo")

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_repo_init_spec_with_alias(self, mock_run):
        mock_run.return_value = subprocess.CompletedProcess(
            None, 0, _FAKE_REPO_INFO)

        repo = cipd_utils.Repo("/repo/root", spec={"baz": "baz_alias"})

        self.assertEqual(len(repo.git_repos), 1)
        self.assertEqual(
            repo.git_repos["baz_alias"].repo_path, "/repo/root/baz")

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_repo_init_spec_unused(self, mock_run):
        mock_run.return_value = subprocess.CompletedProcess(
            None, 0, _FAKE_REPO_INFO)

        with self.assertRaises(ValueError):
            cipd_utils.Repo("/repo/root", spec={"foo": None, "unknown": None})

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_repo_init_spec_name_collision(self, mock_run):
        mock_run.return_value = subprocess.CompletedProcess(
            None, 0, _FAKE_REPO_INFO)

        with self.assertRaises(ValueError):
            cipd_utils.Repo(
                "/repo/root", spec={
                    "foo": "same_alias",
                    "baz": "same_alias"
                })


class CipdTests(unittest.TestCase):

    @mock.patch.object(
        cipd_utils.os.path, "isdir", autospec=True, return_value=False)
    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_cipd_manifest(self, mock_run, _mock_isdir):

        # The code under test will download the CIPD package into a tempdir
        # so we don't know the path ahead of time. In order to inject a fake
        # manifest, this function will write it to disk as a side-effect of
        # the mock subprocess.run() call.
        def write_cipd_manifest_side_effect(command, *args, **kwargs):
            # The path to download will follow the "-root" arg.
            download_root = command[command.index("-root") + 1]
            with open(os.path.join(download_root, "manifest.json"), "w") as f:
                f.write(
                    textwrap.dedent(
                        """\
                        {
                            "repo1": "revision1",
                            "repo2": "revision2"
                        }
                        """))

        mock_run.side_effect = write_cipd_manifest_side_effect

        manifest = cipd_utils.get_cipd_version_manifest("package", "version")
        self.assertEqual(manifest, {"repo1": "revision1", "repo2": "revision2"})

    @mock.patch.object(cipd_utils.subprocess, "run", autospec=True)
    def test_cipd_manifest_local(self, mock_run):
        with tempfile.TemporaryDirectory() as temp_dir:
            with open(os.path.join(temp_dir, "manifest.json"), "w") as f:
                f.write(
                    textwrap.dedent(
                        """\
                        {
                            "repo1": "revision1",
                            "repo2": "revision2"
                        }
                        """))

            manifest = cipd_utils.get_cipd_version_manifest("package", temp_dir)

        self.assertEqual(manifest, {"repo1": "revision1", "repo2": "revision2"})

        # We should not have called into `cipd` at all since the package was
        # available locally.
        mock_run.assert_not_called()


def set_up_changelog_mocks(
        mock_get_cipd_version_manifest, cipd_version_a, cipd_version_b,
        repo_info):
    """Configures all the mocks needed to produce a changelog.

    There's a lot of mocking that needs to be done to set up the proper
    CIPD, repo, and git calls. Extracting it here allows the tests to
    just focus on the logic.

    Args:
        mock_get_cipd_version_manifest: get_cipd_version_manifest() mock.
        cipd_version_a: CIPD version A.
        cipd_version_b: CIPD version B.
        repo_info: a {name, info} dict of repos to mock out, where |info| is a
                   tuple (revision A, revision B, A->B commits, B->A commits).

    Returns:
        The mock Repo object to use.
    """

    # Mock out the CIPD manifest for the given repos.
    def cipd_version_manifest(_, cipd_version):
        if cipd_version == cipd_version_a:
            git_rev_index = 0
        elif cipd_version == cipd_version_b:
            git_rev_index = 1
        else:
            raise ValueError(f"Unexpected CIPD version {cipd_version}")

        manifest = {}
        for name, info in repo_info.items():
            git_rev = info[git_rev_index]
            if git_rev:
                manifest[name] = git_rev
        return manifest

    mock_get_cipd_version_manifest.side_effect = cipd_version_manifest

    # Mock out the Repo and each Git sub-object.
    mock_repo = mock.Mock(spec=cipd_utils.Repo)
    mock_repo.git_repos = {}

    for name, info in repo_info.items():
        mock_git = mock.Mock(spec=cipd_utils.Git)

        # Python functions are late-binding, meaning the variables will be
        # captured at call-time, not at definition. So we need a wrapper here
        # that we can call immediately to bind the loop variables, or else
        # they'll change on the next loop iteration.
        def wrap_changelog():
            rev_a, rev_b, a_to_b, b_to_a = info

            def changelog(old_revision, new_revision):
                if old_revision == rev_a and new_revision == rev_b:
                    return "\n".join(a_to_b)
                elif old_revision == rev_b and new_revision == rev_a:
                    return "\n".join(b_to_a)
                raise ValueError(
                    f"Unknown {name} revisions {old_revision}, {new_revision}")

            return changelog

        mock_git.changelog.side_effect = wrap_changelog()
        mock_repo.git_repos[name] = mock_git

    return mock_repo


class ChangelogTests(unittest.TestCase):

    @mock.patch.object(cipd_utils, "get_cipd_version_manifest", autospec=True)
    def test_changelog(self, mock_get_cipd_version_manifest):
        mock_repo = set_up_changelog_mocks(
            mock_get_cipd_version_manifest, "cipd_ver_A", "cipd_ver_B", {
                "repo1":
                    [
                        "rev1_A",
                        "rev1_B",
                        ["[repo1] commit 1", "[repo1] commit 2"],
                        [],
                    ],
                "repo2":
                    [
                        "rev2_A",
                        "rev2_B",
                        [
                            "[repo2] commit 1", "[repo2] commit 2",
                            "[repo2] commit 3"
                        ],
                        [],
                    ]
            })

        changelog = cipd_utils.changelog(
            mock_repo, "package_name", "cipd_ver_A", "cipd_ver_B")
        self.assertEqual(
            changelog,
            textwrap.dedent(
                """\
                -- Changelist --
                repo1:
                [repo1] commit 1
                [repo1] commit 2

                repo2:
                [repo2] commit 1
                [repo2] commit 2
                [repo2] commit 3

                -- Source Revisions --
                repo1: rev1_B
                repo2: rev2_B"""))

    @mock.patch.object(cipd_utils, "get_cipd_version_manifest", autospec=True)
    def test_changelog_new_repo(self, mock_get_cipd_version_manifest):
        mock_repo = set_up_changelog_mocks(
            mock_get_cipd_version_manifest,
            "cipd_ver_A",
            "cipd_ver_B",
            {
                "repo1":
                    [
                        None,  # Repo does not exist in the first version.
                        "rev1_B",
                        ["[repo1] commit 1", "[repo1] commit 2"],
                        [],
                    ],
            })

        changelog = cipd_utils.changelog(
            mock_repo, "package_name", "cipd_ver_A", "cipd_ver_B")
        self.assertEqual(
            changelog,
            textwrap.dedent(
                """\
                -- Changelist --
                repo1:
                [repo1] commit 1
                [repo1] commit 2

                -- Source Revisions --
                repo1: rev1_B"""))

    @mock.patch.object(cipd_utils, "get_cipd_version_manifest", autospec=True)
    def test_changelog_deleted_repo(self, mock_get_cipd_version_manifest):
        mock_repo = set_up_changelog_mocks(
            mock_get_cipd_version_manifest,
            "cipd_ver_A",
            "cipd_ver_B",
            {
                "repo1":
                    [
                        "rev1_A",
                        "rev1_B",
                        ["[repo1] commit 1", "[repo1] commit 2"],
                        [],
                    ],
                "repo2":
                    [
                        "rev2_A",
                        None,  # Repo does not exist in the second version.
                        ["[repo2] this should not be printed"],
                        ["[repo2] this should not be printed either"],
                    ]
            })

        changelog = cipd_utils.changelog(
            mock_repo, "package_name", "cipd_ver_A", "cipd_ver_B")
        self.assertEqual(
            changelog,
            textwrap.dedent(
                """\
                -- Changelist --
                repo1:
                [repo1] commit 1
                [repo1] commit 2

                repo2:
                [removed commits:]
                [repo has been removed]

                -- Source Revisions --
                repo1: rev1_B"""))

    @mock.patch.object(cipd_utils, "get_cipd_version_manifest", autospec=True)
    def test_changelog_removed_commits(self, mock_get_cipd_version_manifest):
        mock_repo = set_up_changelog_mocks(
            mock_get_cipd_version_manifest,
            "cipd_ver_A",
            "cipd_ver_B",
            {
                "repo1":
                    [
                        "rev1_A",
                        "rev1_B",
                        ["[repo1] commit 1", "[repo1] commit 2"],
                        # A is not a direct ancestor of B - it had a commit that
                        # no longer exists in the new version.
                        ["[repo1] removed commit"],
                    ]
            })

        changelog = cipd_utils.changelog(
            mock_repo, "package_name", "cipd_ver_A", "cipd_ver_B")
        self.assertEqual(
            changelog,
            textwrap.dedent(
                """\
                -- Changelist --
                repo1:
                [repo1] commit 1
                [repo1] commit 2
                [removed commits:]
                [repo1] removed commit

                -- Source Revisions --
                repo1: rev1_B"""))

    @mock.patch.object(cipd_utils, "get_cipd_version_manifest", autospec=True)
    def test_changelog_no_changes(self, mock_get_cipd_version_manifest):
        mock_repo = set_up_changelog_mocks(
            mock_get_cipd_version_manifest, "cipd_ver_A", "cipd_ver_B",
            {"repo1": [
                "rev1_no_change",
                "rev1_no_change",
                [],
                [],
            ]})

        changelog = cipd_utils.changelog(
            mock_repo, "package_name", "cipd_ver_A", "cipd_ver_B")
        self.assertEqual(
            changelog,
            textwrap.dedent(
                """\
                -- Changelist --
                [no changes]

                -- Source Revisions --
                repo1: rev1_no_change"""))


if __name__ == "__main__":
    unittest.main()
