#!/usr/bin/env fuchsia-vendored-python
# Copyright 2024 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 compute_content_hash.py"""

import os
import subprocess
import sys
import tempfile
import typing as T
import unittest
from pathlib import Path

sys.path.insert(0, os.path.dirname(__file__))
import compute_content_hash as cch


def _git_cmd(git_dir: Path, args: T.Sequence[str | Path]) -> str:
    """Run git command in a given directory. Return output as a string."""
    ret = subprocess.run(
        ["git", "-C", str(git_dir)] + [str(a) for a in args],
        check=True,
        text=True,
        capture_output=True,
    )
    return ret.stdout.strip()


def _setup_first_git_dir(git_dir: Path) -> tuple[str, str]:
    git_dir.mkdir(parents=True)
    _git_cmd(git_dir, ["init"])
    # required to avoid errors on CI build bots when running this test.
    _git_cmd(git_dir, ["config", "--local", "user.email", "test@example.com"])
    _git_cmd(git_dir, ["config", "--local", "user.name", "Test User"])

    (git_dir / "foo").write_text("1")
    _git_cmd(git_dir, ["add", "foo"])
    _git_cmd(git_dir, ["commit", "-m", "first commit"])
    first_commit = _git_cmd(git_dir, ["rev-parse", "HEAD"])
    (git_dir / "foo").write_text("2")
    _git_cmd(git_dir, ["commit", "-am", "second commit"])
    second_commit = _git_cmd(git_dir, ["rev-parse", "HEAD"])
    return (first_commit, second_commit)


def _setup_second_git_dir(git_dir: Path, submodule_path: Path) -> str:
    git_dir.mkdir(parents=True)
    _git_cmd(git_dir, ["init"])
    # required to avoid errors on CI build bots when running this test.
    _git_cmd(git_dir, ["config", "--local", "user.email", "test@example.com"])
    _git_cmd(git_dir, ["config", "--local", "user.name", "Test User"])

    # Add a submodule. Using -c protocol.file.allow=always
    # is required to avoid an error message that says:
    # "fatal: transport 'file' not allowed".
    # See https://github.com/flatpak/flatpak-builder/issues/495#issuecomment-1297413908
    _git_cmd(
        git_dir,
        [
            "-c",
            "protocol.file.allow=always",
            "submodule",
            "add",
            submodule_path,
            "sub1",
        ],
    )
    _git_cmd(git_dir, ["commit", "-m", "first commit"])
    return _git_cmd(git_dir, ["rev-parse", "HEAD"])


class ComputeContentHashTest(unittest.TestCase):
    def setUp(self):
        self._td = tempfile.TemporaryDirectory()
        self._dir = Path(self._td.name)
        self.datadir = self._dir / "data"
        self.datadir.mkdir(parents=True)
        (self.datadir / "README.txt").write_text("Example input file.\n")
        (self.datadir / "subdir").mkdir()
        (self.datadir / "subdir" / "data").write_text("42")
        (self.datadir / "data.link").symlink_to("subdir/data")

        self.prebuiltdir = self._dir / "cipd_prebuilt"
        self.prebuiltdir.mkdir()
        (self.prebuiltdir / ".versions").mkdir()
        (self.prebuiltdir / ".versions" / "bar.cipd_version").write_text(
            "version 1.0"
        )

    def tearDown(self):
        self._td.cleanup()

    def _setup_git_repos(self):
        self.gitdir1 = self._dir / "git_project1"
        self.first_commit, self.second_commit = _setup_first_git_dir(
            self.gitdir1
        )

        self.gitdir2 = self._dir / "git_project2"
        self.first_commit2 = _setup_second_git_dir(self.gitdir2, self.gitdir1)

    def test_file_content_hash(self):
        fstate = cch.FileState()
        descriptor = fstate.process_source_path(self.datadir / "README.txt")
        self.assertEqual(
            descriptor, "F49d18153ca1983adefbe9c3a2cb91676c73b1024"
        )

    def test_symlink_content_hash(self):
        fstate = cch.FileState()
        descriptor = fstate.process_source_path(self.datadir / "data.link")
        self.assertEqual(descriptor, "Ssubdir/data")

    def test_directory_content_hash(self):
        fstate = cch.FileState()
        descriptor = fstate.process_source_path(self.datadir)
        self.assertEqual(
            descriptor,
            """D
 README.txt F49d18153ca1983adefbe9c3a2cb91676c73b1024
 data.link Ssubdir/data
 subdir/data F92cfceb39d57d914ed8b14d0e37643de0797ae56
""",
        )

    def test_cipd_content_hash(self):
        fstate = cch.FileState()
        descriptor = fstate.process_source_path(self.prebuiltdir)
        self.assertEqual(
            descriptor,
            """D
 .versions/bar.cipd_version F105a6be87e08ee0d67f397a498315de3afaba803
""",
        )
        fstate = cch.FileState(cipd_names=["bar"])
        descriptor = fstate.process_source_path(self.prebuiltdir)
        self.assertEqual(
            descriptor, "F105a6be87e08ee0d67f397a498315de3afaba803"
        )

    def test_git_content_hash_no_submodules(self):
        self._setup_git_repos()

        # on branch on first git repository.
        fstate = cch.FileState()
        descriptor = fstate.process_source_path(self.gitdir1)
        self.assertEqual(descriptor, "G" + self.second_commit)

        # detached HEAD on first git repository.
        _git_cmd(self.gitdir1, ["checkout", self.first_commit])
        fstate = cch.FileState()
        descriptor = fstate.process_source_path(self.gitdir1)
        self.assertEqual(descriptor, "G" + self.first_commit)

        # on branch on second git repository + on branch in submodule
        fstate = cch.FileState()
        descriptor = fstate.process_source_path(self.gitdir2)
        self.assertEqual(descriptor, "G" + self.first_commit2)


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