from __future__ import annotations

import enum
import pickle

import pytest

import env
from pybind11_tests import native_enum as m

SMALLENUM_MEMBERS = (
    ("a", 0),
    ("b", 1),
    ("c", 2),
)

COLOR_MEMBERS = (
    ("red", 0),
    ("yellow", 1),
    ("green", 20),
    ("blue", 21),
)

ALTITUDE_MEMBERS = (
    ("high", "h"),
    ("low", "l"),
)

FLAGS_UCHAR_MEMBERS = (
    ("bit0", 0x1),
    ("bit1", 0x2),
    ("bit2", 0x4),
)

FLAGS_UINT_MEMBERS = (
    ("bit0", 0x1),
    ("bit1", 0x2),
    ("bit2", 0x4),
)

CLASS_WITH_ENUM_IN_CLASS_MEMBERS = (
    ("one", 0),
    ("two", 1),
)

EXPORT_VALUES_MEMBERS = (
    ("exv0", 0),
    ("exv1", 1),
)

MEMBER_DOC_MEMBERS = (
    ("mem0", 0),
    ("mem1", 1),
    ("mem2", 2),
)

FUNC_SIG_RENDERING_MEMBERS = ()

ENUM_TYPES_AND_MEMBERS = (
    (m.smallenum, SMALLENUM_MEMBERS),
    (m.color, COLOR_MEMBERS),
    (m.flags_uchar, FLAGS_UCHAR_MEMBERS),
    (m.flags_uint, FLAGS_UINT_MEMBERS),
    (m.export_values, EXPORT_VALUES_MEMBERS),
    (m.member_doc, MEMBER_DOC_MEMBERS),
    (m.func_sig_rendering, FUNC_SIG_RENDERING_MEMBERS),
    (m.class_with_enum.in_class, CLASS_WITH_ENUM_IN_CLASS_MEMBERS),
)

ENUM_TYPES = [_[0] for _ in ENUM_TYPES_AND_MEMBERS]


@pytest.mark.parametrize("enum_type", ENUM_TYPES)
def test_enum_type(enum_type):
    assert isinstance(enum_type, enum.EnumMeta)
    assert enum_type.__module__ == m.__name__


@pytest.mark.parametrize(("enum_type", "members"), ENUM_TYPES_AND_MEMBERS)
def test_enum_members(enum_type, members):
    for name, value in members:
        assert enum_type[name].value == value


@pytest.mark.parametrize(("enum_type", "members"), ENUM_TYPES_AND_MEMBERS)
def test_pickle_roundtrip(enum_type, members):
    for name, _ in members:
        orig = enum_type[name]
        # This only works if __module__ is correct.
        serialized = pickle.dumps(orig)
        restored = pickle.loads(serialized)
        assert restored == orig


@pytest.mark.parametrize("enum_type", [m.flags_uchar, m.flags_uint])
def test_enum_flag(enum_type):
    bits02 = enum_type.bit0 | enum_type.bit2
    assert enum_type.bit0 in bits02
    assert enum_type.bit1 not in bits02
    assert enum_type.bit2 in bits02


def test_export_values():
    assert m.exv0 is m.export_values.exv0
    assert m.exv1 is m.export_values.exv1


def test_class_doc():
    pure_native = enum.IntEnum("pure_native", (("mem", 0),))
    assert m.smallenum.__doc__ == "doc smallenum"
    assert m.color.__doc__ == pure_native.__doc__


def test_member_doc():
    pure_native = enum.IntEnum("pure_native", (("mem", 0),))
    assert m.member_doc.mem0.__doc__ == "docA"
    assert m.member_doc.mem1.__doc__ == pure_native.mem.__doc__
    assert m.member_doc.mem2.__doc__ == "docC"


def test_pybind11_isinstance_color():
    for name, _ in COLOR_MEMBERS:
        assert m.isinstance_color(m.color[name])
    assert not m.isinstance_color(m.color)
    for name, _ in SMALLENUM_MEMBERS:
        assert not m.isinstance_color(m.smallenum[name])
    assert not m.isinstance_color(m.smallenum)
    assert not m.isinstance_color(None)


def test_pass_color_success():
    for name, value in COLOR_MEMBERS:
        assert m.pass_color(m.color[name]) == value


def test_pass_color_fail():
    with pytest.raises(TypeError) as excinfo:
        m.pass_color(None)
    assert "pybind11_tests.native_enum.color" in str(excinfo.value)


def test_return_color_success():
    for name, value in COLOR_MEMBERS:
        assert m.return_color(value) == m.color[name]


def test_return_color_fail():
    with pytest.raises(ValueError) as excinfo_direct:
        m.color(2)
    with pytest.raises(ValueError) as excinfo_cast:
        m.return_color(2)
    assert str(excinfo_cast.value) == str(excinfo_direct.value)


def test_return_color_ptr():
    assert m.return_color_const_ptr() == m.color.red
    assert m.return_color_mutbl_ptr() == m.color.green


def test_property_type_hint():
    prop = m.class_with_enum.__dict__["nested_value"]
    assert isinstance(prop, property)
    assert prop.fget.__doc__.startswith(
        "(self: pybind11_tests.native_enum.class_with_enum)"
        " -> pybind11_tests.native_enum.class_with_enum.in_class"
    )


def test_func_sig_rendering():
    assert m.pass_and_return_func_sig_rendering.__doc__.startswith(
        "pass_and_return_func_sig_rendering(e: pybind11_tests.native_enum.func_sig_rendering)"
        " -> pybind11_tests.native_enum.func_sig_rendering"
    )


def test_type_caster_enum_type_enabled_false():
    # This is really only a "does it compile" test.
    assert m.pass_some_proto_enum(None) is None
    assert m.return_some_proto_enum() is None


@pytest.mark.skipif(isinstance(m.obj_cast_color_ptr, str), reason=m.obj_cast_color_ptr)
def test_obj_cast_color_ptr():
    with pytest.raises(RuntimeError) as excinfo:
        m.obj_cast_color_ptr(m.color.red)
    assert str(excinfo.value) == "Unable to cast native enum type to reference"


def test_py_cast_color_handle():
    for name, value in COLOR_MEMBERS:
        assert m.py_cast_color_handle(m.color[name]) == value


def test_exercise_import_or_getattr_leading_dot():
    with pytest.raises(ValueError) as excinfo:
        m.exercise_import_or_getattr(m, ".")
    assert str(excinfo.value) == "Invalid fully-qualified name `.` (native_type_name)"


def test_exercise_import_or_getattr_bad_top_level():
    with pytest.raises(ImportError) as excinfo:
        m.exercise_import_or_getattr(m, "NeVeRLaNd")
    assert (
        str(excinfo.value)
        == "Failed to import top-level module `NeVeRLaNd` (native_type_name)"
    )


def test_exercise_import_or_getattr_dot_dot():
    with pytest.raises(ValueError) as excinfo:
        m.exercise_import_or_getattr(m, "enum..")
    assert (
        str(excinfo.value) == "Invalid fully-qualified name `enum..` (native_type_name)"
    )


def test_exercise_import_or_getattr_bad_enum_attr():
    with pytest.raises(ImportError) as excinfo:
        m.exercise_import_or_getattr(m, "enum.NoNeXiStInG")
    lines = str(excinfo.value).splitlines()
    assert len(lines) >= 5
    assert (
        lines[0]
        == "Failed to import or getattr `NoNeXiStInG` from `enum` (native_type_name)"
    )
    assert lines[1] == "-------- getattr exception --------"
    ix = lines.index("-------- import exception --------")
    assert ix >= 3
    assert len(lines) > ix + 0


def test_native_enum_data_missing_finalize_error_message():
    msg = m.native_enum_data_missing_finalize_error_message("Fake")
    assert msg == 'pybind11::native_enum<...>("Fake", ...): MISSING .finalize()'


@pytest.mark.parametrize(
    "func", [m.native_enum_ctor_malformed_utf8, m.native_enum_value_malformed_utf8]
)
def test_native_enum_malformed_utf8(func):
    if env.GRAALPY and func is m.native_enum_ctor_malformed_utf8:
        pytest.skip("GraalPy does not raise UnicodeDecodeError")
    malformed_utf8 = b"\x80"
    with pytest.raises(UnicodeDecodeError):
        func(malformed_utf8)


def test_native_enum_double_finalize():
    with pytest.raises(RuntimeError) as excinfo:
        m.native_enum_double_finalize(m)
    assert (
        str(excinfo.value)
        == 'pybind11::native_enum<...>("fake_native_enum_double_finalize"): DOUBLE finalize'
    )


def test_native_enum_value_after_finalize():
    with pytest.raises(RuntimeError) as excinfo:
        m.native_enum_value_after_finalize(m)
    assert (
        str(excinfo.value)
        == 'pybind11::native_enum<...>("fake_native_enum_value_after_finalize"): value after finalize'
    )


def test_double_registration_native_enum():
    with pytest.raises(RuntimeError) as excinfo:
        m.double_registration_native_enum(m)
    assert (
        str(excinfo.value)
        == 'pybind11::native_enum<...>("fake_double_registration_native_enum") is already registered!'
    )


def test_native_enum_name_clash():
    m.fake_native_enum_name_clash = None
    with pytest.raises(RuntimeError) as excinfo:
        m.native_enum_name_clash(m)
    assert (
        str(excinfo.value)
        == 'pybind11::native_enum<...>("fake_native_enum_name_clash"):'
        " an object with that name is already defined"
    )


def test_native_enum_value_name_clash():
    m.fake_native_enum_value_name_clash_x = None
    with pytest.raises(RuntimeError) as excinfo:
        m.native_enum_value_name_clash(m)
    assert (
        str(excinfo.value)
        == 'pybind11::native_enum<...>("fake_native_enum_value_name_clash")'
        '.value("fake_native_enum_value_name_clash_x"):'
        " an object with that name is already defined"
    )


def test_double_registration_enum_before_native_enum():
    with pytest.raises(RuntimeError) as excinfo:
        m.double_registration_enum_before_native_enum(m)
    assert (
        str(excinfo.value)
        == 'pybind11::native_enum<...>("fake_enum_first") is already registered'
        " as a `pybind11::enum_` or `pybind11::class_`!"
    )


def test_double_registration_native_enum_before_enum():
    with pytest.raises(RuntimeError) as excinfo:
        m.double_registration_native_enum_before_enum(m)
    assert (
        str(excinfo.value)
        == 'pybind11::enum_ "name_must_be_different_to_reach_desired_code_path"'
        " is already registered as a pybind11::native_enum!"
    )


def test_native_enum_missing_finalize_failure():
    if not isinstance(m.native_enum_missing_finalize_failure, str):
        m.native_enum_missing_finalize_failure()
        pytest.fail("Process termination expected.")


def test_unregister_native_enum_when_destroyed():
    # For stability when running tests in parallel, this test should be the
    # only one that touches `m.altitude` or calls `m.bind_altitude`.

    def test_altitude_enum():
        # Logic copied from test_enum_type / test_enum_members.
        # We don't test altitude there to avoid possible clashes if
        # parallelizing against other tests in this file, and we also
        # don't want to hold any references to the enumerators that
        # would prevent GCing the enum type below.
        assert isinstance(m.altitude, enum.EnumMeta)
        assert m.altitude.__module__ == m.__name__
        for name, value in ALTITUDE_MEMBERS:
            assert m.altitude[name].value == value

    def test_altitude_binding():
        assert m.is_high_altitude(m.altitude.high)
        assert not m.is_high_altitude(m.altitude.low)
        assert m.get_altitude() is m.altitude.high
        with pytest.raises(TypeError, match="incompatible function arguments"):
            m.is_high_altitude("oops")

    m.bind_altitude(m)
    test_altitude_enum()
    test_altitude_binding()

    if env.TYPES_ARE_IMMORTAL:
        pytest.skip("can't GC type objects on this platform")

    # Delete the enum type. Returning an instance from Python should fail
    # rather than accessing a deleted object.
    pytest.delattr_and_ensure_destroyed((m, "altitude"))
    with pytest.raises(TypeError, match="Unable to convert function return"):
        m.get_altitude()
    with pytest.raises(TypeError, match="incompatible function arguments"):
        m.is_high_altitude("oops")

    # Recreate the enum type; should not have any duplicate-binding error
    m.bind_altitude(m)
    test_altitude_enum()
    test_altitude_binding()

    # Remove the pybind11 capsule without removing the type; enum is still
    # usable but can't be passed to/from bound functions
    del m.altitude.__pybind11_native_enum__
    pytest.gc_collect()
    test_altitude_enum()  # enum itself still works

    with pytest.raises(TypeError, match="Unable to convert function return"):
        m.get_altitude()
    with pytest.raises(TypeError, match="incompatible function arguments"):
        m.is_high_altitude(m.altitude.high)

    del m.altitude
