#!/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
from pathlib import Path
import tempfile
import unittest
import unittest.mock as 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_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."""
    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(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_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('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)

  @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()
