#!/usr/bin/env python3
# Copyright 2022 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 for the patch_utils.py file."""

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

import patch_utils as pu


class TestPatchUtils(unittest.TestCase):
    """Test the patch_utils."""

    def test_atomic_write(self):
        """Test that atomic write safely writes."""
        prior_contents = "This is a test written by patch_utils_unittest.py\n"
        new_contents = "I am a test written by patch_utils_unittest.py\n"
        with tempfile.TemporaryDirectory(
            prefix="patch_utils_unittest"
        ) as dirname:
            dirpath = Path(dirname)
            filepath = dirpath / "test_atomic_write.txt"
            with filepath.open("w", encoding="utf-8") as f:
                f.write(prior_contents)

            def _t():
                with pu.atomic_write(filepath, encoding="utf-8") as f:
                    f.write(new_contents)
                    raise Exception("Expected failure")

            self.assertRaises(Exception, _t)
            with filepath.open(encoding="utf-8") as f:
                lines = f.readlines()
            self.assertEqual(lines[0], prior_contents)
            with pu.atomic_write(filepath, encoding="utf-8") as f:
                f.write(new_contents)
            with filepath.open(encoding="utf-8") as f:
                lines = f.readlines()
            self.assertEqual(lines[0], new_contents)

    def test_from_to_dict(self):
        """Test to and from dict conversion."""
        d = TestPatchUtils._default_json_dict()
        d["metadata"] = {
            "title": "hello world",
            "info": [],
            "other_extra_info": {
                "extra_flags": [],
            },
        }
        e = pu.PatchEntry.from_dict(TestPatchUtils._mock_dir(), d)
        self.assertEqual(d, e.to_dict())

    def test_patch_path(self):
        """Test that we can get the full path from a PatchEntry."""
        d = TestPatchUtils._default_json_dict()
        with mock.patch.object(Path, "is_dir", return_value=True):
            entry = pu.PatchEntry.from_dict(Path("/home/dir"), d)
            self.assertEqual(
                entry.patch_path(), Path("/home/dir") / d["rel_patch_path"]
            )

    def test_can_patch_version(self):
        """Test that patch application based on version is correct."""
        base_dict = TestPatchUtils._default_json_dict()
        workdir = TestPatchUtils._mock_dir()
        e1 = pu.PatchEntry.from_dict(workdir, base_dict)
        self.assertFalse(e1.can_patch_version(3))
        self.assertTrue(e1.can_patch_version(4))
        self.assertTrue(e1.can_patch_version(5))
        self.assertFalse(e1.can_patch_version(9))
        base_dict["version_range"] = {"until": 9}
        e2 = pu.PatchEntry.from_dict(workdir, base_dict)
        self.assertTrue(e2.can_patch_version(0))
        self.assertTrue(e2.can_patch_version(5))
        self.assertFalse(e2.can_patch_version(9))
        base_dict["version_range"] = {"from": 4}
        e3 = pu.PatchEntry.from_dict(workdir, base_dict)
        self.assertFalse(e3.can_patch_version(3))
        self.assertTrue(e3.can_patch_version(5))
        self.assertTrue(e3.can_patch_version(1 << 31))
        base_dict["version_range"] = {"from": 4, "until": None}
        e4 = pu.PatchEntry.from_dict(workdir, base_dict)
        self.assertFalse(e4.can_patch_version(3))
        self.assertTrue(e4.can_patch_version(5))
        self.assertTrue(e4.can_patch_version(1 << 31))
        base_dict["version_range"] = {"from": None, "until": 9}
        e5 = pu.PatchEntry.from_dict(workdir, base_dict)
        self.assertTrue(e5.can_patch_version(0))
        self.assertTrue(e5.can_patch_version(5))
        self.assertFalse(e5.can_patch_version(9))

    def test_can_parse_from_json(self):
        """Test that patches be loaded from json."""
        patches_json = """
[
  {
    "metadata": {},
    "platforms": [],
    "rel_patch_path": "cherry/nowhere.patch",
    "version_range": {}
  },
  {
    "metadata": {},
    "rel_patch_path": "cherry/somewhere.patch",
    "version_range": {}
  },
  {
    "rel_patch_path": "where.patch",
    "version_range": null
  },
  {
    "rel_patch_path": "cherry/anywhere.patch"
  }
]
    """
        result = pu.json_to_patch_entries(Path(), io.StringIO(patches_json))
        self.assertEqual(len(result), 4)

    def test_parsed_hunks(self):
        """Test that we can parse patch file hunks."""
        m = mock.mock_open(read_data=_EXAMPLE_PATCH)

        def mocked_open(self, *args, **kwargs):
            return m(self, *args, **kwargs)

        with mock.patch.object(Path, "open", mocked_open):
            e = pu.PatchEntry.from_dict(
                TestPatchUtils._mock_dir(), TestPatchUtils._default_json_dict()
            )
            hunk_dict = e.parsed_hunks()

        m.assert_called()
        filename1 = "clang/lib/Driver/ToolChains/Clang.cpp"
        filename2 = "llvm/lib/Passes/PassBuilder.cpp"
        self.assertEqual(set(hunk_dict.keys()), {filename1, filename2})
        hunk_list1 = hunk_dict[filename1]
        hunk_list2 = hunk_dict[filename2]
        self.assertEqual(len(hunk_list1), 1)
        self.assertEqual(len(hunk_list2), 2)

    def test_apply_when_patch_nonexistent(self):
        """Test that we error out when we try to apply a non-existent patch."""
        src_dir = TestPatchUtils._mock_dir("somewhere/llvm-project")
        patch_dir = TestPatchUtils._mock_dir()
        e = pu.PatchEntry.from_dict(
            patch_dir, TestPatchUtils._default_json_dict()
        )
        with mock.patch("subprocess.run", mock.MagicMock()):
            self.assertRaises(RuntimeError, lambda: e.apply(src_dir))

    def test_apply_success(self):
        """Test that we can call apply."""
        src_dir = TestPatchUtils._mock_dir("somewhere/llvm-project")
        patch_dir = TestPatchUtils._mock_dir()
        e = pu.PatchEntry.from_dict(
            patch_dir, TestPatchUtils._default_json_dict()
        )
        with mock.patch("pathlib.Path.is_file", return_value=True):
            with mock.patch("subprocess.run", mock.MagicMock()):
                result = e.apply(src_dir)
        self.assertTrue(result.succeeded)

    def test_parse_failed_patch_output(self):
        """Test that we can call parse `patch` output."""
        fixture = """
checking file a/b/c.cpp
Hunk #1 SUCCEEDED at 96 with fuzz 1.
Hunk #12 FAILED at 77.
Hunk #42 FAILED at 1979.
checking file x/y/z.h
Hunk #4 FAILED at 30.
checking file works.cpp
Hunk #1 SUCCEEDED at 96 with fuzz 1.
"""
        result = pu.parse_failed_patch_output(fixture)
        self.assertEqual(result["a/b/c.cpp"], [12, 42])
        self.assertEqual(result["x/y/z.h"], [4])
        self.assertNotIn("works.cpp", result)

    def test_is_git_dirty(self):
        """Test if a git directory has uncommitted changes."""
        with tempfile.TemporaryDirectory(
            prefix="patch_utils_unittest"
        ) as dirname:
            dirpath = Path(dirname)

            def _run_h(cmd):
                subprocess.run(
                    cmd,
                    cwd=dirpath,
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                    check=True,
                )

            _run_h(["git", "init"])
            self.assertFalse(pu.is_git_dirty(dirpath))
            test_file = dirpath / "test_file"
            test_file.touch()
            self.assertTrue(pu.is_git_dirty(dirpath))
            _run_h(["git", "add", "."])
            _run_h(["git", "commit", "-m", "test"])
            self.assertFalse(pu.is_git_dirty(dirpath))
            test_file.touch()
            self.assertFalse(pu.is_git_dirty(dirpath))
            with test_file.open("w", encoding="utf-8"):
                test_file.write_text("abc")
            self.assertTrue(pu.is_git_dirty(dirpath))

    @mock.patch("patch_utils.git_clean_context", mock.MagicMock)
    def test_update_version_ranges(self):
        """Test the UpdateVersionRanges function."""
        with tempfile.TemporaryDirectory(
            prefix="patch_manager_unittest"
        ) as dirname:
            dirpath = Path(dirname)
            patches = [
                pu.PatchEntry(
                    workdir=dirpath,
                    rel_patch_path="x.patch",
                    metadata=None,
                    platforms=None,
                    version_range={
                        "from": 0,
                        "until": 2,
                    },
                ),
                pu.PatchEntry(
                    workdir=dirpath,
                    rel_patch_path="y.patch",
                    metadata=None,
                    platforms=None,
                    version_range={
                        "from": 0,
                        "until": 2,
                    },
                ),
            ]
            patches[0].apply = mock.MagicMock(
                return_value=pu.PatchResult(
                    succeeded=False, failed_hunks={"a/b/c": []}
                )
            )
            patches[1].apply = mock.MagicMock(
                return_value=pu.PatchResult(succeeded=True)
            )
            results, _ = pu.update_version_ranges_with_entries(
                1, dirpath, patches
            )
            # We should only have updated the version_range of the first patch,
            # as that one failed to apply.
            self.assertEqual(len(results), 1)
            self.assertEqual(results[0].version_range, {"from": 0, "until": 1})
            self.assertEqual(patches[0].version_range, {"from": 0, "until": 1})
            self.assertEqual(patches[1].version_range, {"from": 0, "until": 2})

    @mock.patch("builtins.print")
    def test_remove_old_patches(self, _):
        """Can remove old patches from PATCHES.json."""
        one_patch_dict = {
            "metadata": {
                "title": "[some label] hello world",
            },
            "platforms": [
                "chromiumos",
            ],
            "rel_patch_path": "x/y/z",
            "version_range": {
                "from": 4,
                "until": 5,
            },
        }
        patches = [
            one_patch_dict,
            {**one_patch_dict, "version_range": {"until": None}},
            {**one_patch_dict, "version_range": {"from": 100}},
            {**one_patch_dict, "version_range": {"until": 8}},
        ]
        cases = [
            (0, lambda x: self.assertEqual(len(x), 4)),
            (6, lambda x: self.assertEqual(len(x), 3)),
            (8, lambda x: self.assertEqual(len(x), 2)),
            (1000, lambda x: self.assertEqual(len(x), 2)),
        ]

        def _t(dirname: str, svn_version: int, assertion_f: Callable):
            json_filepath = Path(dirname) / "PATCHES.json"
            with json_filepath.open("w", encoding="utf-8") as f:
                json.dump(patches, f)
            pu.remove_old_patches(svn_version, Path(), json_filepath)
            with json_filepath.open("r", encoding="utf-8") as f:
                result = json.load(f)
            assertion_f(result)

        with tempfile.TemporaryDirectory(
            prefix="patch_utils_unittest"
        ) as dirname:
            for r, a in cases:
                _t(dirname, r, a)

    @staticmethod
    def _default_json_dict():
        return {
            "metadata": {
                "title": "hello world",
            },
            "platforms": ["a"],
            "rel_patch_path": "x/y/z",
            "version_range": {
                "from": 4,
                "until": 9,
            },
        }

    @staticmethod
    def _mock_dir(path: str = "a/b/c"):
        workdir = Path(path)
        workdir = mock.MagicMock(workdir)
        workdir.is_dir = lambda: True
        workdir.joinpath = lambda x: Path(path).joinpath(x)
        workdir.__truediv__ = lambda self, x: self.joinpath(x)
        return workdir


_EXAMPLE_PATCH = """
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 5620a543438..099eb769ca5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3995,8 +3995,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       Args.hasArg(options::OPT_dA))
     CmdArgs.push_back("-masm-verbose");

-  if (!TC.useIntegratedAs())
+  if (!TC.useIntegratedAs()) {
     CmdArgs.push_back("-no-integrated-as");
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("-enable-call-graph-profile-sort=false");
+  }

   if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
     CmdArgs.push_back("-mdebug-pass");
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index c5fd68299eb..4c6e15eeeb9 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -212,6 +212,10 @@ static cl::opt<bool>
     EnableCHR("enable-chr-npm", cl::init(true), cl::Hidden,
               cl::desc("Enable control height reduction optimization (CHR)"));

+static cl::opt<bool> EnableCallGraphProfileSort(
+    "enable-call-graph-profile-sort", cl::init(true), cl::Hidden,
+    cl::desc("Enable call graph profile pass for the new PM (default = on)"));
+
 extern cl::opt<bool> EnableHotColdSplit;
 extern cl::opt<bool> EnableOrderFileInstrumentation;

@@ -939,7 +943,8 @@ ModulePassManager PassBuilder::buildModuleOptimizationPipeline(
   // Add the core optimizing pipeline.
   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(OptimizePM)));

-  MPM.addPass(CGProfilePass());
+  if (EnableCallGraphProfileSort)
+    MPM.addPass(CGProfilePass());

   // Now we need to do some global optimization transforms.
   // FIXME: It would seem like these should come first in the optimization
"""

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