# Copyright (C) 2021 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 git_superproject.py module."""

import json
import os
import platform
import tempfile
import unittest
from unittest import mock

from test_manifest_xml import sort_attributes

import git_superproject
import git_trace2_event_log
import manifest_xml


class SuperprojectTestCase(unittest.TestCase):
    """TestCase for the Superproject module."""

    PARENT_SID_KEY = "GIT_TRACE2_PARENT_SID"
    PARENT_SID_VALUE = "parent_sid"
    SELF_SID_REGEX = r"repo-\d+T\d+Z-.*"
    FULL_SID_REGEX = rf"^{PARENT_SID_VALUE}/{SELF_SID_REGEX}"

    def setUp(self):
        """Set up superproject every time."""
        self.tempdirobj = tempfile.TemporaryDirectory(prefix="repo_tests")
        self.tempdir = self.tempdirobj.name
        self.repodir = os.path.join(self.tempdir, ".repo")
        self.manifest_file = os.path.join(
            self.repodir, manifest_xml.MANIFEST_FILE_NAME
        )
        os.mkdir(self.repodir)
        self.platform = platform.system().lower()

        # By default we initialize with the expected case where
        # repo launches us (so GIT_TRACE2_PARENT_SID is set).
        env = {
            self.PARENT_SID_KEY: self.PARENT_SID_VALUE,
        }
        self.git_event_log = git_trace2_event_log.EventLog(env=env)

        # The manifest parsing really wants a git repo currently.
        gitdir = os.path.join(self.repodir, "manifests.git")
        os.mkdir(gitdir)
        with open(os.path.join(gitdir, "config"), "w") as fp:
            fp.write(
                """[remote "origin"]
        url = https://localhost:0/manifest
"""
            )

        manifest = self.getXmlManifest(
            """
<manifest>
  <remote name="default-remote" fetch="http://localhost" />
  <default remote="default-remote" revision="refs/heads/main" />
  <superproject name="superproject"/>
  <project path="art" name="platform/art" groups="notdefault,platform-"""
            + self.platform
            + """
  " /></manifest>
"""
        )
        self._superproject = git_superproject.Superproject(
            manifest,
            name="superproject",
            remote=manifest.remotes.get("default-remote").ToRemoteSpec(
                "superproject"
            ),
            revision="refs/heads/main",
        )

    def tearDown(self):
        """Tear down superproject every time."""
        self.tempdirobj.cleanup()

    def getXmlManifest(self, data):
        """Helper to initialize a manifest for testing."""
        with open(self.manifest_file, "w") as fp:
            fp.write(data)
        return manifest_xml.XmlManifest(self.repodir, self.manifest_file)

    def verifyCommonKeys(self, log_entry, expected_event_name, full_sid=True):
        """Helper function to verify common event log keys."""
        self.assertIn("event", log_entry)
        self.assertIn("sid", log_entry)
        self.assertIn("thread", log_entry)
        self.assertIn("time", log_entry)

        # Do basic data format validation.
        self.assertEqual(expected_event_name, log_entry["event"])
        if full_sid:
            self.assertRegex(log_entry["sid"], self.FULL_SID_REGEX)
        else:
            self.assertRegex(log_entry["sid"], self.SELF_SID_REGEX)
        self.assertRegex(
            log_entry["time"], r"^\d+-\d+-\d+T\d+:\d+:\d+\.\d+\+00:00$"
        )

    def readLog(self, log_path):
        """Helper function to read log data into a list."""
        log_data = []
        with open(log_path, mode="rb") as f:
            for line in f:
                log_data.append(json.loads(line))
        return log_data

    def verifyErrorEvent(self):
        """Helper to verify that error event is written."""

        with tempfile.TemporaryDirectory(prefix="event_log_tests") as tempdir:
            log_path = self.git_event_log.Write(path=tempdir)
            self.log_data = self.readLog(log_path)

        self.assertEqual(len(self.log_data), 2)
        error_event = self.log_data[1]
        self.verifyCommonKeys(self.log_data[0], expected_event_name="version")
        self.verifyCommonKeys(error_event, expected_event_name="error")
        # Check for 'error' event specific fields.
        self.assertIn("msg", error_event)
        self.assertIn("fmt", error_event)

    def test_superproject_get_superproject_no_superproject(self):
        """Test with no url."""
        manifest = self.getXmlManifest(
            """
<manifest>
</manifest>
"""
        )
        self.assertIsNone(manifest.superproject)

    def test_superproject_get_superproject_invalid_url(self):
        """Test with an invalid url."""
        manifest = self.getXmlManifest(
            """
<manifest>
  <remote name="test-remote" fetch="localhost" />
  <default remote="test-remote" revision="refs/heads/main" />
  <superproject name="superproject"/>
</manifest>
"""
        )
        superproject = git_superproject.Superproject(
            manifest,
            name="superproject",
            remote=manifest.remotes.get("test-remote").ToRemoteSpec(
                "superproject"
            ),
            revision="refs/heads/main",
        )
        sync_result = superproject.Sync(self.git_event_log)
        self.assertFalse(sync_result.success)
        self.assertTrue(sync_result.fatal)

    def test_superproject_get_superproject_invalid_branch(self):
        """Test with an invalid branch."""
        manifest = self.getXmlManifest(
            """
<manifest>
  <remote name="test-remote" fetch="localhost" />
  <default remote="test-remote" revision="refs/heads/main" />
  <superproject name="superproject"/>
</manifest>
"""
        )
        self._superproject = git_superproject.Superproject(
            manifest,
            name="superproject",
            remote=manifest.remotes.get("test-remote").ToRemoteSpec(
                "superproject"
            ),
            revision="refs/heads/main",
        )
        with mock.patch.object(self._superproject, "_branch", "junk"):
            sync_result = self._superproject.Sync(self.git_event_log)
            self.assertFalse(sync_result.success)
            self.assertTrue(sync_result.fatal)
            self.verifyErrorEvent()

    def test_superproject_get_superproject_mock_init(self):
        """Test with _Init failing."""
        with mock.patch.object(self._superproject, "_Init", return_value=False):
            sync_result = self._superproject.Sync(self.git_event_log)
            self.assertFalse(sync_result.success)
            self.assertTrue(sync_result.fatal)

    def test_superproject_get_superproject_mock_fetch(self):
        """Test with _Fetch failing."""
        with mock.patch.object(self._superproject, "_Init", return_value=True):
            os.mkdir(self._superproject._superproject_path)
            with mock.patch.object(
                self._superproject, "_Fetch", return_value=False
            ):
                sync_result = self._superproject.Sync(self.git_event_log)
                self.assertFalse(sync_result.success)
                self.assertTrue(sync_result.fatal)

    def test_superproject_get_all_project_commit_ids_mock_ls_tree(self):
        """Test with LsTree being a mock."""
        data = (
            "120000 blob 158258bdf146f159218e2b90f8b699c4d85b5804\tAndroid.bp\x00"
            "160000 commit 2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea\tart\x00"
            "160000 commit e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06\tbootable/recovery\x00"
            "120000 blob acc2cbdf438f9d2141f0ae424cec1d8fc4b5d97f\tbootstrap.bash\x00"
            "160000 commit ade9b7a0d874e25fff4bf2552488825c6f111928\tbuild/bazel\x00"
        )
        with mock.patch.object(self._superproject, "_Init", return_value=True):
            with mock.patch.object(
                self._superproject, "_Fetch", return_value=True
            ):
                with mock.patch.object(
                    self._superproject, "_LsTree", return_value=data
                ):
                    commit_ids_result = (
                        self._superproject._GetAllProjectsCommitIds()
                    )
                    self.assertEqual(
                        commit_ids_result.commit_ids,
                        {
                            "art": "2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea",
                            "bootable/recovery": "e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06",
                            "build/bazel": "ade9b7a0d874e25fff4bf2552488825c6f111928",
                        },
                    )
                    self.assertFalse(commit_ids_result.fatal)

    def test_superproject_write_manifest_file(self):
        """Test with writing manifest to a file after setting revisionId."""
        self.assertEqual(len(self._superproject._manifest.projects), 1)
        project = self._superproject._manifest.projects[0]
        project.SetRevisionId("ABCDEF")
        # Create temporary directory so that it can write the file.
        os.mkdir(self._superproject._superproject_path)
        manifest_path = self._superproject._WriteManifestFile()
        self.assertIsNotNone(manifest_path)
        with open(manifest_path) as fp:
            manifest_xml_data = fp.read()
        self.assertEqual(
            sort_attributes(manifest_xml_data),
            '<?xml version="1.0" ?><manifest>'
            '<remote fetch="http://localhost" name="default-remote"/>'
            '<default remote="default-remote" revision="refs/heads/main"/>'
            '<project groups="notdefault,platform-' + self.platform + '" '
            'name="platform/art" path="art" revision="ABCDEF" upstream="refs/heads/main"/>'
            '<superproject name="superproject"/>'
            "</manifest>",
        )

    def test_superproject_update_project_revision_id(self):
        """Test with LsTree being a mock."""
        self.assertEqual(len(self._superproject._manifest.projects), 1)
        projects = self._superproject._manifest.projects
        data = (
            "160000 commit 2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea\tart\x00"
            "160000 commit e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06\tbootable/recovery\x00"
        )
        with mock.patch.object(self._superproject, "_Init", return_value=True):
            with mock.patch.object(
                self._superproject, "_Fetch", return_value=True
            ):
                with mock.patch.object(
                    self._superproject, "_LsTree", return_value=data
                ):
                    # Create temporary directory so that it can write the file.
                    os.mkdir(self._superproject._superproject_path)
                    update_result = self._superproject.UpdateProjectsRevisionId(
                        projects, self.git_event_log
                    )
                    self.assertIsNotNone(update_result.manifest_path)
                    self.assertFalse(update_result.fatal)
                    with open(update_result.manifest_path) as fp:
                        manifest_xml_data = fp.read()
                    self.assertEqual(
                        sort_attributes(manifest_xml_data),
                        '<?xml version="1.0" ?><manifest>'
                        '<remote fetch="http://localhost" name="default-remote"/>'
                        '<default remote="default-remote" revision="refs/heads/main"/>'
                        '<project groups="notdefault,platform-'
                        + self.platform
                        + '" '
                        'name="platform/art" path="art" '
                        'revision="2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea" upstream="refs/heads/main"/>'
                        '<superproject name="superproject"/>'
                        "</manifest>",
                    )

    def test_superproject_update_project_revision_id_no_superproject_tag(self):
        """Test update of commit ids of a manifest without superproject tag."""
        manifest = self.getXmlManifest(
            """
<manifest>
  <remote name="default-remote" fetch="http://localhost" />
  <default remote="default-remote" revision="refs/heads/main" />
  <project name="test-name"/>
</manifest>
"""
        )
        self.maxDiff = None
        self.assertIsNone(manifest.superproject)
        self.assertEqual(
            sort_attributes(manifest.ToXml().toxml()),
            '<?xml version="1.0" ?><manifest>'
            '<remote fetch="http://localhost" name="default-remote"/>'
            '<default remote="default-remote" revision="refs/heads/main"/>'
            '<project name="test-name"/>'
            "</manifest>",
        )

    def test_superproject_update_project_revision_id_from_local_manifest_group(
        self,
    ):
        """Test update of commit ids of a manifest that have local manifest no superproject group."""
        local_group = manifest_xml.LOCAL_MANIFEST_GROUP_PREFIX + ":local"
        manifest = self.getXmlManifest(
            """
<manifest>
  <remote name="default-remote" fetch="http://localhost" />
  <remote name="goog" fetch="http://localhost2" />
  <default remote="default-remote" revision="refs/heads/main" />
  <superproject name="superproject"/>
  <project path="vendor/x" name="platform/vendor/x" remote="goog"
           groups=\""""
            + local_group
            + """
         " revision="master-with-vendor" clone-depth="1" />
  <project path="art" name="platform/art" groups="notdefault,platform-"""
            + self.platform
            + """
  " /></manifest>
"""
        )
        self.maxDiff = None
        self._superproject = git_superproject.Superproject(
            manifest,
            name="superproject",
            remote=manifest.remotes.get("default-remote").ToRemoteSpec(
                "superproject"
            ),
            revision="refs/heads/main",
        )
        self.assertEqual(len(self._superproject._manifest.projects), 2)
        projects = self._superproject._manifest.projects
        data = "160000 commit 2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea\tart\x00"
        with mock.patch.object(self._superproject, "_Init", return_value=True):
            with mock.patch.object(
                self._superproject, "_Fetch", return_value=True
            ):
                with mock.patch.object(
                    self._superproject, "_LsTree", return_value=data
                ):
                    # Create temporary directory so that it can write the file.
                    os.mkdir(self._superproject._superproject_path)
                    update_result = self._superproject.UpdateProjectsRevisionId(
                        projects, self.git_event_log
                    )
                    self.assertIsNotNone(update_result.manifest_path)
                    self.assertFalse(update_result.fatal)
                    with open(update_result.manifest_path) as fp:
                        manifest_xml_data = fp.read()
                    # Verify platform/vendor/x's project revision hasn't
                    # changed.
                    self.assertEqual(
                        sort_attributes(manifest_xml_data),
                        '<?xml version="1.0" ?><manifest>'
                        '<remote fetch="http://localhost" name="default-remote"/>'
                        '<remote fetch="http://localhost2" name="goog"/>'
                        '<default remote="default-remote" revision="refs/heads/main"/>'
                        '<project groups="notdefault,platform-'
                        + self.platform
                        + '" '
                        'name="platform/art" path="art" '
                        'revision="2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea" upstream="refs/heads/main"/>'
                        '<superproject name="superproject"/>'
                        "</manifest>",
                    )

    def test_superproject_update_project_revision_id_with_pinned_manifest(self):
        """Test update of commit ids of a pinned manifest."""
        manifest = self.getXmlManifest(
            """
<manifest>
  <remote name="default-remote" fetch="http://localhost" />
  <default remote="default-remote" revision="refs/heads/main" />
  <superproject name="superproject"/>
  <project path="vendor/x" name="platform/vendor/x" revision="" />
  <project path="vendor/y" name="platform/vendor/y"
           revision="52d3c9f7c107839ece2319d077de0cd922aa9d8f" />
  <project path="art" name="platform/art" groups="notdefault,platform-"""
            + self.platform
            + """
  " /></manifest>
"""
        )
        self.maxDiff = None
        self._superproject = git_superproject.Superproject(
            manifest,
            name="superproject",
            remote=manifest.remotes.get("default-remote").ToRemoteSpec(
                "superproject"
            ),
            revision="refs/heads/main",
        )
        self.assertEqual(len(self._superproject._manifest.projects), 3)
        projects = self._superproject._manifest.projects
        data = (
            "160000 commit 2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea\tart\x00"
            "160000 commit e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06\tvendor/x\x00"
        )
        with mock.patch.object(self._superproject, "_Init", return_value=True):
            with mock.patch.object(
                self._superproject, "_Fetch", return_value=True
            ):
                with mock.patch.object(
                    self._superproject, "_LsTree", return_value=data
                ):
                    # Create temporary directory so that it can write the file.
                    os.mkdir(self._superproject._superproject_path)
                    update_result = self._superproject.UpdateProjectsRevisionId(
                        projects, self.git_event_log
                    )
                    self.assertIsNotNone(update_result.manifest_path)
                    self.assertFalse(update_result.fatal)
                    with open(update_result.manifest_path) as fp:
                        manifest_xml_data = fp.read()
                    # Verify platform/vendor/x's project revision hasn't
                    # changed.
                    self.assertEqual(
                        sort_attributes(manifest_xml_data),
                        '<?xml version="1.0" ?><manifest>'
                        '<remote fetch="http://localhost" name="default-remote"/>'
                        '<default remote="default-remote" revision="refs/heads/main"/>'
                        '<project groups="notdefault,platform-'
                        + self.platform
                        + '" '
                        'name="platform/art" path="art" '
                        'revision="2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea" upstream="refs/heads/main"/>'
                        '<project name="platform/vendor/x" path="vendor/x" '
                        'revision="e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06" upstream="refs/heads/main"/>'
                        '<project name="platform/vendor/y" path="vendor/y" '
                        'revision="52d3c9f7c107839ece2319d077de0cd922aa9d8f"/>'
                        '<superproject name="superproject"/>'
                        "</manifest>",
                    )

    def test_Fetch(self):
        manifest = self.getXmlManifest(
            """
<manifest>
  <remote name="default-remote" fetch="http://localhost" />
  <default remote="default-remote" revision="refs/heads/main" />
  <superproject name="superproject"/>
  " /></manifest>
"""
        )
        self.maxDiff = None
        self._superproject = git_superproject.Superproject(
            manifest,
            name="superproject",
            remote=manifest.remotes.get("default-remote").ToRemoteSpec(
                "superproject"
            ),
            revision="refs/heads/main",
        )
        os.mkdir(self._superproject._superproject_path)
        os.mkdir(self._superproject._work_git)
        with mock.patch.object(self._superproject, "_Init", return_value=True):
            with mock.patch(
                "git_superproject.GitCommand", autospec=True
            ) as mock_git_command:
                with mock.patch(
                    "git_superproject.GitRefs.get", autospec=True
                ) as mock_git_refs:
                    instance = mock_git_command.return_value
                    instance.Wait.return_value = 0
                    mock_git_refs.side_effect = ["", "1234"]

                    self.assertTrue(self._superproject._Fetch())
                    self.assertEqual(
                        # TODO: Once we require Python 3.8+,
                        #  use 'mock_git_command.call_args.args'.
                        mock_git_command.call_args[0],
                        (
                            None,
                            [
                                "fetch",
                                "http://localhost/superproject",
                                "--depth",
                                "1",
                                "--force",
                                "--no-tags",
                                "--filter",
                                "blob:none",
                                "refs/heads/main:refs/heads/main",
                            ],
                        ),
                    )

                    # If branch for revision exists, set as --negotiation-tip.
                    self.assertTrue(self._superproject._Fetch())
                    self.assertEqual(
                        # TODO: Once we require Python 3.8+,
                        #  use 'mock_git_command.call_args.args'.
                        mock_git_command.call_args[0],
                        (
                            None,
                            [
                                "fetch",
                                "http://localhost/superproject",
                                "--depth",
                                "1",
                                "--force",
                                "--no-tags",
                                "--filter",
                                "blob:none",
                                "--negotiation-tip",
                                "1234",
                                "refs/heads/main:refs/heads/main",
                            ],
                        ),
                    )
