#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ===----------------------------------------------------------------------===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===----------------------------------------------------------------------===##
"""Tests for revert_checker.

Note that these tests require having LLVM's git history available, since our
repository has a few interesting instances of edge-cases.
"""

import os
import logging
import unittest
from typing import List

import revert_checker

# pylint: disable=protected-access


def get_llvm_project_path() -> str:
    """Returns the path to llvm-project's root."""
    my_dir = os.path.dirname(__file__)
    return os.path.realpath(os.path.join(my_dir, "..", ".."))


class _SilencingFilter(logging.Filter):
    """Silences all log messages.

    Also collects info about log messages that would've been emitted.
    """

    def __init__(self) -> None:
        self.messages: List[str] = []

    def filter(self, record: logging.LogRecord) -> bool:
        self.messages.append(record.getMessage())
        return False


class Test(unittest.TestCase):
    """Tests for revert_checker."""

    def silence_logging(self) -> _SilencingFilter:
        root = logging.getLogger()
        filt = _SilencingFilter()
        root.addFilter(filt)
        self.addCleanup(root.removeFilter, filt)
        return filt

    def test_log_stream_with_known_sha_range(self) -> None:
        start_sha = "e241573d5972d34a323fa5c64774c4207340beb3"
        end_sha = "a7a37517751ffb0f5529011b4ba96e67fcb27510"
        commits = [
            revert_checker._LogEntry(
                "e241573d5972d34a323fa5c64774c4207340beb3",
                "\n".join(
                    (
                        "[mlir] NFC: remove IntegerValueSet / MutableIntegerSet",
                        "",
                        "Summary:",
                        "- these are unused and really not needed now given flat "
                        "affine",
                        "  constraints",
                        "",
                        "Differential Revision: https://reviews.llvm.org/D75792",
                    )
                ),
            ),
            revert_checker._LogEntry(
                "97572fa6e9daecd648873496fd11f7d1e25a55f0",
                "[NFC] use hasAnyOperatorName and hasAnyOverloadedOperatorName "
                "functions in clang-tidy matchers",
            ),
        ]

        logs = list(
            revert_checker._log_stream(
                get_llvm_project_path(),
                root_sha=start_sha,
                end_at_sha=end_sha,
            )
        )
        self.assertEqual(commits, logs)

    def test_reverted_noncommit_object_is_a_nop(self) -> None:
        log_filter = self.silence_logging()
        # c9944df916e41b1014dff5f6f75d52297b48ecdc mentions reverting a non-commit
        # object. It sits between the given base_ref and root.
        reverts = revert_checker.find_reverts(
            git_dir=get_llvm_project_path(),
            across_ref="c9944df916e41b1014dff5f6f75d52297b48ecdc~",
            root="c9944df916e41b1014dff5f6f75d52297b48ecdc",
            max_pr_lookback=50,
        )
        self.assertEqual(reverts, [])

        complaint = (
            "Failed to resolve reverted object "
            "edd18355be574122aaa9abf58c15d8c50fb085a1"
        )
        self.assertTrue(
            any(x.startswith(complaint) for x in log_filter.messages),
            log_filter.messages,
        )

    def test_known_reverts_across_arbitrary_llvm_rev(self) -> None:
        reverts = revert_checker.find_reverts(
            git_dir=get_llvm_project_path(),
            across_ref="c47f971694be0159ffddfee8a75ae515eba91439",
            root="9f981e9adf9c8d29bb80306daf08d2770263ade6",
            max_pr_lookback=50,
        )
        self.assertEqual(
            reverts,
            [
                revert_checker.Revert(
                    sha="4e0fe038f438ae1679eae9e156e1f248595b2373",
                    reverted_sha="65b21282c710afe9c275778820c6e3c1cf46734b",
                ),
                revert_checker.Revert(
                    sha="9f981e9adf9c8d29bb80306daf08d2770263ade6",
                    reverted_sha="4060016fce3e6a0b926ee9fc59e440a612d3a2ec",
                ),
            ],
        )

    def test_pr_based_revert_works(self) -> None:
        reverts = revert_checker.find_reverts(
            git_dir=get_llvm_project_path(),
            # This SHA is a direct child of the reverted SHA expected below.
            across_ref="2d5f3b0a61fb171617012a2c3ba05fd31fb3bb1d",
            # This SHA is a direct child of the revert SHA listed below.
            root="2c01b278580212914ec037bb5dd9b73702dfe7f1",
            max_pr_lookback=50,
        )
        self.assertEqual(
            reverts,
            [
                revert_checker.Revert(
                    # This SHA is a `Reverts ${PR}` for #111004.
                    sha="50866e84d1da8462aeb96607bf6d9e5bbd5869c5",
                    # ...And this was the commit for #111004.
                    reverted_sha="67160c5ab5f5b7fd5fa7851abcfde367c8a9f91b",
                ),
            ],
        )


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