#!/usr/bin/env python3
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests when handling patches."""

import json
from pathlib import Path
import tempfile
from typing import Callable
import unittest
from unittest import mock

import patch_manager
import patch_utils


class PatchManagerTest(unittest.TestCase):
    """Test class when handling patches of packages."""

    # Simulate behavior of 'os.path.isdir()' when the path is not a directory.
    @mock.patch.object(Path, "is_dir", return_value=False)
    def testInvalidDirectoryPassedAsCommandLineArgument(self, mock_isdir):
        src_dir = "/some/path/that/is/not/a/directory"
        patch_metadata_file = "/some/path/that/is/not/a/file"

        # Verify the exception is raised when the command line argument for
        # '--filesdir_path' or '--src_path' is not a directory.
        with self.assertRaises(ValueError):
            patch_manager.main(
                [
                    "--src_path",
                    src_dir,
                    "--patch_metadata_file",
                    patch_metadata_file,
                ]
            )
        mock_isdir.assert_called_once()

    # Simulate behavior of 'os.path.isfile()' when the patch metadata file is does
    # not exist.
    @mock.patch.object(Path, "is_file", return_value=False)
    def testInvalidPathToPatchMetadataFilePassedAsCommandLineArgument(
        self, mock_isfile
    ):
        src_dir = "/some/path/that/is/not/a/directory"
        patch_metadata_file = "/some/path/that/is/not/a/file"

        # Verify the exception is raised when the command line argument for
        # '--filesdir_path' or '--src_path' is not a directory.
        with mock.patch.object(Path, "is_dir", return_value=True):
            with self.assertRaises(ValueError):
                patch_manager.main(
                    [
                        "--src_path",
                        src_dir,
                        "--patch_metadata_file",
                        patch_metadata_file,
                    ]
                )
        mock_isfile.assert_called_once()

    @mock.patch("builtins.print")
    @mock.patch.object(patch_utils, "git_clean_context")
    def testCheckPatchApplies(self, _, mock_git_clean_context):
        """Tests whether we can apply a single patch for a given svn_version."""
        mock_git_clean_context.return_value = mock.MagicMock()
        with tempfile.TemporaryDirectory(
            prefix="patch_manager_unittest"
        ) as dirname:
            dirpath = Path(dirname)
            patch_entries = [
                patch_utils.PatchEntry(
                    dirpath,
                    metadata=None,
                    platforms=[],
                    rel_patch_path="another.patch",
                    version_range={
                        "from": 9,
                        "until": 20,
                    },
                ),
                patch_utils.PatchEntry(
                    dirpath,
                    metadata=None,
                    platforms=["chromiumos"],
                    rel_patch_path="example.patch",
                    version_range={
                        "from": 1,
                        "until": 10,
                    },
                ),
                patch_utils.PatchEntry(
                    dirpath,
                    metadata=None,
                    platforms=["chromiumos"],
                    rel_patch_path="patch_after.patch",
                    version_range={
                        "from": 1,
                        "until": 5,
                    },
                ),
            ]
            patches_path = dirpath / "PATCHES.json"
            with patch_utils.atomic_write(patches_path, encoding="utf-8") as f:
                json.dump([pe.to_dict() for pe in patch_entries], f)

            def _harness1(
                version: int,
                return_value: patch_utils.PatchResult,
                expected: patch_manager.GitBisectionCode,
            ):
                with mock.patch.object(
                    patch_utils.PatchEntry,
                    "apply",
                    return_value=return_value,
                ) as m:
                    result = patch_manager.CheckPatchApplies(
                        version,
                        dirpath,
                        patches_path,
                        "example.patch",
                    )
                    self.assertEqual(result, expected)
                    m.assert_called()

            _harness1(
                1,
                patch_utils.PatchResult(True, {}),
                patch_manager.GitBisectionCode.GOOD,
            )
            _harness1(
                2,
                patch_utils.PatchResult(True, {}),
                patch_manager.GitBisectionCode.GOOD,
            )
            _harness1(
                2,
                patch_utils.PatchResult(False, {}),
                patch_manager.GitBisectionCode.BAD,
            )
            _harness1(
                11,
                patch_utils.PatchResult(False, {}),
                patch_manager.GitBisectionCode.BAD,
            )

            def _harness2(
                version: int,
                application_func: Callable,
                expected: patch_manager.GitBisectionCode,
            ):
                with mock.patch.object(
                    patch_utils,
                    "apply_single_patch_entry",
                    application_func,
                ):
                    result = patch_manager.CheckPatchApplies(
                        version,
                        dirpath,
                        patches_path,
                        "example.patch",
                    )
                    self.assertEqual(result, expected)

            # Check patch can apply and fail with good return codes.
            def _apply_patch_entry_mock1(v, _, patch_entry, **__):
                return patch_entry.can_patch_version(v), None

            _harness2(
                1,
                _apply_patch_entry_mock1,
                patch_manager.GitBisectionCode.GOOD,
            )
            _harness2(
                11,
                _apply_patch_entry_mock1,
                patch_manager.GitBisectionCode.BAD,
            )

            # Early exit check, shouldn't apply later failing patch.
            def _apply_patch_entry_mock2(v, _, patch_entry, **__):
                if (
                    patch_entry.can_patch_version(v)
                    and patch_entry.rel_patch_path == "patch_after.patch"
                ):
                    return False, {"filename": mock.Mock()}
                return True, None

            _harness2(
                1,
                _apply_patch_entry_mock2,
                patch_manager.GitBisectionCode.GOOD,
            )

            # Skip check, should exit early on the first patch.
            def _apply_patch_entry_mock3(v, _, patch_entry, **__):
                if (
                    patch_entry.can_patch_version(v)
                    and patch_entry.rel_patch_path == "another.patch"
                ):
                    return False, {"filename": mock.Mock()}
                return True, None

            _harness2(
                9,
                _apply_patch_entry_mock3,
                patch_manager.GitBisectionCode.SKIP,
            )


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