from __future__ import annotations

import re
import sys

import pytest
from custom_exceptions import PythonMyException7

import env
import pybind11_cross_module_tests as cm
import pybind11_tests
from pybind11_tests import exceptions as m


def test_std_exception(msg):
    with pytest.raises(RuntimeError) as excinfo:
        m.throw_std_exception()
    assert msg(excinfo.value) == "This exception was intentionally thrown."


def test_error_already_set(msg):
    with pytest.raises(RuntimeError) as excinfo:
        m.throw_already_set(False)
    assert (
        msg(excinfo.value)
        == "Internal error: pybind11::error_already_set called while Python error indicator not set."
    )

    with pytest.raises(ValueError) as excinfo:
        m.throw_already_set(True)
    assert msg(excinfo.value) == "foo"


def test_raise_from(msg):
    with pytest.raises(ValueError) as excinfo:
        m.raise_from()
    assert msg(excinfo.value) == "outer"
    assert msg(excinfo.value.__cause__) == "inner"


def test_raise_from_already_set(msg):
    with pytest.raises(ValueError) as excinfo:
        m.raise_from_already_set()
    assert msg(excinfo.value) == "outer"
    assert msg(excinfo.value.__cause__) == "inner"


def test_cross_module_exceptions(msg):
    with pytest.raises(RuntimeError) as excinfo:
        cm.raise_runtime_error()
    assert str(excinfo.value) == "My runtime error"

    with pytest.raises(ValueError) as excinfo:
        cm.raise_value_error()
    assert str(excinfo.value) == "My value error"

    with pytest.raises(ValueError) as excinfo:
        cm.throw_pybind_value_error()
    assert str(excinfo.value) == "pybind11 value error"

    with pytest.raises(TypeError) as excinfo:
        cm.throw_pybind_type_error()
    assert str(excinfo.value) == "pybind11 type error"

    with pytest.raises(StopIteration) as excinfo:
        cm.throw_stop_iteration()

    with pytest.raises(cm.LocalSimpleException) as excinfo:
        cm.throw_local_simple_error()
    assert msg(excinfo.value) == "external mod"

    with pytest.raises(KeyError) as excinfo:
        cm.throw_local_error()
    # KeyError is a repr of the key, so it has an extra set of quotes
    assert str(excinfo.value) == "'just local'"


@pytest.mark.xfail(
    "(env.MACOS and env.PYPY_PRE_7_3_23) or env.ANDROID or env.FREEBSD",
    raises=RuntimeError,
    reason="See Issue #2847, PR #2999, PR #4324, PR #5925",
)
def test_cross_module_exception_translator():
    with pytest.raises(KeyError):
        # translator registered in cross_module_tests
        m.throw_should_be_translated_to_key_error()


def test_python_call_in_catch():
    d = {}
    assert m.python_call_in_destructor(d) is True
    assert d["good"] is True


def ignore_pytest_unraisable_warning(f):
    unraisable = "PytestUnraisableExceptionWarning"
    if hasattr(pytest, unraisable):  # Python >= 3.8 and pytest >= 6
        dec = pytest.mark.filterwarnings(f"ignore::pytest.{unraisable}")
        return dec(f)
    return f


# TODO: find out why this fails on PyPy, https://foss.heptapod.net/pypy/pypy/-/issues/3583
@pytest.mark.xfail(env.PYPY, reason="Failure on PyPy 3.8 (7.3.7)", strict=False)
@ignore_pytest_unraisable_warning
def test_python_alreadyset_in_destructor(monkeypatch, capsys):
    triggered = False

    # Don't take `sys.unraisablehook`, as that's overwritten by pytest
    default_hook = sys.__unraisablehook__

    def hook(unraisable_hook_args):
        exc_type, exc_value, exc_tb, err_msg, obj = unraisable_hook_args
        if obj == "already_set demo":
            nonlocal triggered
            triggered = True
        default_hook(unraisable_hook_args)
        return

    # Use monkeypatch so pytest can apply and remove the patch as appropriate
    monkeypatch.setattr(sys, "unraisablehook", hook)

    assert m.python_alreadyset_in_destructor("already_set demo") is True
    assert triggered is True

    _, captured_stderr = capsys.readouterr()
    # Strip ANSI codes that Python 3.15+ adds to this traceback under FORCE_COLOR.
    captured_stderr = re.sub(r"\x1b\[[0-?]*[ -/]*m", "", captured_stderr)
    assert captured_stderr.startswith("Exception ignored in: 'already_set demo'")
    assert captured_stderr.rstrip().endswith("KeyError: 'bar'")


def test_exception_matches():
    assert m.exception_matches()
    assert m.exception_matches_base()
    assert m.modulenotfound_exception_matches_base()


def test_custom(msg):
    # Can we catch a MyException?
    with pytest.raises(m.MyException) as excinfo:
        m.throws1()
    assert msg(excinfo.value) == "this error should go to py::exception<MyException>"

    # Can we catch a MyExceptionUseDeprecatedOperatorCall?
    with pytest.raises(m.MyExceptionUseDeprecatedOperatorCall) as excinfo:
        m.throws1d()
    assert (
        msg(excinfo.value)
        == "this error should go to py::exception<MyExceptionUseDeprecatedOperatorCall>"
    )

    # Can we translate to standard Python exceptions?
    with pytest.raises(RuntimeError) as excinfo:
        m.throws2()
    assert msg(excinfo.value) == "this error should go to a standard Python exception"

    # Can we handle unknown exceptions?
    with pytest.raises(RuntimeError) as excinfo:
        m.throws3()
    assert msg(excinfo.value) == "Caught an unknown exception!"

    # Can we delegate to another handler by rethrowing?
    with pytest.raises(m.MyException) as excinfo:
        m.throws4()
    assert msg(excinfo.value) == "this error is rethrown"

    # Can we fall-through to the default handler?
    with pytest.raises(RuntimeError) as excinfo:
        m.throws_logic_error()
    assert (
        msg(excinfo.value) == "this error should fall through to the standard handler"
    )

    # OverFlow error translation.
    with pytest.raises(OverflowError) as excinfo:
        m.throws_overflow_error()

    # Can we handle a helper-declared exception?
    with pytest.raises(m.MyException5) as excinfo:
        m.throws5()
    assert msg(excinfo.value) == "this is a helper-defined translated exception"

    # Exception subclassing:
    with pytest.raises(m.MyException5) as excinfo:
        m.throws5_1()
    assert msg(excinfo.value) == "MyException5 subclass"
    assert isinstance(excinfo.value, m.MyException5_1)

    with pytest.raises(m.MyException5_1) as excinfo:
        m.throws5_1()
    assert msg(excinfo.value) == "MyException5 subclass"

    with pytest.raises(m.MyException5) as excinfo:  # noqa: PT012
        try:
            m.throws5()
        except m.MyException5_1 as err:
            raise RuntimeError("Exception error: caught child from parent") from err
    assert msg(excinfo.value) == "this is a helper-defined translated exception"

    with pytest.raises(PythonMyException7) as excinfo:
        m.throws7()
    assert msg(excinfo.value) == "[PythonMyException7]: abc"


@pytest.mark.xfail("env.GRAALPY", reason="TODO should get fixed on GraalPy side")
def test_nested_throws(capture):
    """Tests nested (e.g. C++ -> Python -> C++) exception handling"""

    def throw_myex():
        raise m.MyException("nested error")

    def throw_myex5():
        raise m.MyException5("nested error 5")

    # In the comments below, the exception is caught in the first step, thrown in the last step

    # C++ -> Python
    with capture:
        m.try_catch(m.MyException5, throw_myex5)
    assert str(capture).startswith("MyException5: nested error 5")

    # Python -> C++ -> Python
    with pytest.raises(m.MyException) as excinfo:
        m.try_catch(m.MyException5, throw_myex)
    assert str(excinfo.value) == "nested error"

    def pycatch(exctype, f, *args):  # noqa: ARG001
        try:
            f(*args)
        except m.MyException as e:
            print(e)

    # C++ -> Python -> C++ -> Python
    with capture:
        m.try_catch(
            m.MyException5,
            pycatch,
            m.MyException,
            m.try_catch,
            m.MyException,
            throw_myex5,
        )
    assert str(capture).startswith("MyException5: nested error 5")

    # C++ -> Python -> C++
    with capture:
        m.try_catch(m.MyException, pycatch, m.MyException5, m.throws4)
    assert capture == "this error is rethrown"

    # Python -> C++ -> Python -> C++
    with pytest.raises(m.MyException5) as excinfo:
        m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)
    assert str(excinfo.value) == "this is a helper-defined translated exception"


# TODO: Investigate this crash, see pybind/pybind11#5062 for background
@pytest.mark.skipif(
    sys.platform.startswith("win32") and "Clang" in pybind11_tests.compiler_info,
    reason="Started segfaulting February 2024",
)
def test_throw_nested_exception():
    with pytest.raises(RuntimeError) as excinfo:
        m.throw_nested_exception()
    assert str(excinfo.value) == "Outer Exception"
    assert str(excinfo.value.__cause__) == "Inner Exception"


# This can often happen if you wrap a pybind11 class in a Python wrapper
def test_invalid_repr():
    class MyRepr:
        def __repr__(self):
            raise AttributeError("Example error")

    with pytest.raises(TypeError):
        m.simple_bool_passthrough(MyRepr())


def test_local_translator(msg):
    """Tests that a local translator works and that the local translator from
    the cross module is not applied"""
    with pytest.raises(RuntimeError) as excinfo:
        m.throws6()
    assert msg(excinfo.value) == "MyException6 only handled in this module"

    with pytest.raises(RuntimeError) as excinfo:
        m.throws_local_error()
    assert not isinstance(excinfo.value, KeyError)
    assert msg(excinfo.value) == "never caught"

    with pytest.raises(Exception) as excinfo:
        m.throws_local_simple_error()
    assert not isinstance(excinfo.value, cm.LocalSimpleException)
    assert msg(excinfo.value) == "this mod"


def test_error_already_set_message_with_unicode_surrogate():  # Issue #4288
    assert m.error_already_set_what(RuntimeError, "\ud927") == (
        "RuntimeError: \\ud927",
        False,
    )


def test_error_already_set_message_with_malformed_utf8():
    assert m.error_already_set_what(RuntimeError, b"\x80") == (
        "RuntimeError: b'\\x80'",
        False,
    )


class FlakyException(Exception):
    def __init__(self, failure_point):
        if failure_point == "failure_point_init":
            raise ValueError("triggered_failure_point_init")
        self.failure_point = failure_point

    def __str__(self):
        if self.failure_point == "failure_point_str":
            raise ValueError("triggered_failure_point_str")
        return "FlakyException.__str__"


@pytest.mark.parametrize(
    ("exc_type", "exc_value", "expected_what"),
    [
        (ValueError, "plain_str", "ValueError: plain_str"),
        (ValueError, ("tuple_elem",), "ValueError: tuple_elem"),
        (FlakyException, ("happy",), "FlakyException: FlakyException.__str__"),
    ],
)
def test_error_already_set_what_with_happy_exceptions(
    exc_type, exc_value, expected_what
):
    what, py_err_set_after_what = m.error_already_set_what(exc_type, exc_value)
    assert not py_err_set_after_what
    assert what == expected_what


def _test_flaky_exception_failure_point_init_before_py_3_12():
    with pytest.raises(RuntimeError) as excinfo:
        m.error_already_set_what(FlakyException, ("failure_point_init",))
    lines = str(excinfo.value).splitlines()
    # PyErr_NormalizeException replaces the original FlakyException with ValueError:
    assert lines[:3] == [
        "pybind11::error_already_set: MISMATCH of original and normalized active exception types:"
        " ORIGINAL FlakyException REPLACED BY ValueError: triggered_failure_point_init",
        "",
        "At:",
    ]
    # Checking the first two lines of the traceback as formatted in error_string():
    assert "test_exceptions.py(" in lines[3]
    assert lines[3].endswith("): __init__")
    assert lines[4].endswith(
        "): _test_flaky_exception_failure_point_init_before_py_3_12"
    )


def _test_flaky_exception_failure_point_init_py_3_12():
    # Behavior change in Python 3.12: https://github.com/python/cpython/issues/102594
    what, py_err_set_after_what = m.error_already_set_what(
        FlakyException, ("failure_point_init",)
    )
    assert not py_err_set_after_what
    lines = what.splitlines()
    assert lines[0].endswith("ValueError[WITH __notes__]: triggered_failure_point_init")
    assert lines[1] == "__notes__ (len=1):"
    assert "Normalization failed:" in lines[2]
    assert "FlakyException" in lines[2]


@pytest.mark.skipif(
    "env.PYPY and sys.version_info[:2] < (3, 12)",
    reason="PyErr_NormalizeException Segmentation fault",
)
@pytest.mark.xfail("env.GRAALPY", reason="TODO should be fixed on GraalPy side")
def test_flaky_exception_failure_point_init():
    if sys.version_info[:2] < (3, 12):
        _test_flaky_exception_failure_point_init_before_py_3_12()
    else:
        _test_flaky_exception_failure_point_init_py_3_12()


@pytest.mark.xfail("env.GRAALPY", reason="TODO should be fixed on GraalPy side")
def test_flaky_exception_failure_point_str():
    what, py_err_set_after_what = m.error_already_set_what(
        FlakyException, ("failure_point_str",)
    )
    assert not py_err_set_after_what
    lines = what.splitlines()
    n = 3 if env.PYPY and len(lines) == 3 else 5
    assert (
        lines[:n]
        == [
            "FlakyException: <MESSAGE UNAVAILABLE DUE TO ANOTHER EXCEPTION>",
            "",
            "MESSAGE UNAVAILABLE DUE TO EXCEPTION: ValueError: triggered_failure_point_str",
            "",
            "At:",
        ][:n]
    )


def test_cross_module_interleaved_error_already_set():
    with pytest.raises(RuntimeError) as excinfo:
        m.test_cross_module_interleaved_error_already_set()
    assert str(excinfo.value) in (
        "2nd error.",  # Almost all platforms.
        "RuntimeError: 2nd error.",  # Some PyPy builds (seen under macOS).
    )


def test_error_already_set_double_restore():
    m.test_error_already_set_double_restore(True)  # dry_run
    with pytest.raises(RuntimeError) as excinfo:
        m.test_error_already_set_double_restore(False)
    assert str(excinfo.value) == (
        "Internal error: pybind11::detail::error_fetch_and_normalize::restore()"
        " called a second time. ORIGINAL ERROR: ValueError: Random error."
    )


def test_pypy_oserror_normalization():
    # https://github.com/pybind/pybind11/issues/4075
    what = m.test_pypy_oserror_normalization()
    assert "this_filename_must_not_exist" in what


def test_fn_cast_int_exception():
    with pytest.raises(RuntimeError) as excinfo:
        m.test_fn_cast_int(lambda: None)

    assert str(excinfo.value).startswith(
        "Unable to cast Python instance of type <class 'NoneType'> to C++ type"
    )


def test_return_exception_void():
    with pytest.raises(TypeError) as excinfo:
        m.return_exception_void()
    assert "Exception" in str(excinfo.value)
