import pytest

import env
from pybind11_tests import ConstructorStats, UserType
from pybind11_tests import class_ as m


def test_obj_class_name():
    expected_name = "UserType" if env.PYPY else "pybind11_tests.UserType"
    assert m.obj_class_name(UserType(1)) == expected_name
    assert m.obj_class_name(UserType) == expected_name


def test_repr():
    assert "pybind11_type" in repr(type(UserType))
    assert "UserType" in repr(UserType)


def test_instance(msg):
    with pytest.raises(TypeError) as excinfo:
        m.NoConstructor()
    assert msg(excinfo.value) == "m.class_.NoConstructor: No constructor defined!"

    instance = m.NoConstructor.new_instance()

    cstats = ConstructorStats.get(m.NoConstructor)
    assert cstats.alive() == 1
    del instance
    assert cstats.alive() == 0


def test_instance_new():
    instance = m.NoConstructorNew()  # .__new__(m.NoConstructor.__class__)
    cstats = ConstructorStats.get(m.NoConstructorNew)
    assert cstats.alive() == 1
    del instance
    assert cstats.alive() == 0


def test_type():
    assert m.check_type(1) == m.DerivedClass1
    with pytest.raises(RuntimeError) as execinfo:
        m.check_type(0)

    assert "pybind11::detail::get_type_info: unable to find type info" in str(
        execinfo.value
    )
    assert "Invalid" in str(execinfo.value)

    # Currently not supported
    # See https://github.com/pybind/pybind11/issues/2486
    # assert m.check_type(2) == int


def test_type_of_py():
    assert m.get_type_of(1) == int
    assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1
    assert m.get_type_of(int) == type


def test_type_of_classic():
    assert m.get_type_classic(1) == int
    assert m.get_type_classic(m.DerivedClass1()) == m.DerivedClass1
    assert m.get_type_classic(int) == type


def test_type_of_py_nodelete():
    # If the above test deleted the class, this will segfault
    assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1


def test_as_type_py():
    assert m.as_type(int) == int

    with pytest.raises(TypeError):
        assert m.as_type(1) == int

    with pytest.raises(TypeError):
        assert m.as_type(m.DerivedClass1()) == m.DerivedClass1


def test_docstrings(doc):
    assert doc(UserType) == "A `py::class_` type for testing"
    assert UserType.__name__ == "UserType"
    assert UserType.__module__ == "pybind11_tests"
    assert UserType.get_value.__name__ == "get_value"
    assert UserType.get_value.__module__ == "pybind11_tests"

    assert (
        doc(UserType.get_value)
        == """
        get_value(self: m.UserType) -> int

        Get value using a method
    """
    )
    assert doc(UserType.value) == "Get/set value using a property"

    assert (
        doc(m.NoConstructor.new_instance)
        == """
        new_instance() -> m.class_.NoConstructor

        Return an instance
    """
    )


def test_qualname(doc):
    """Tests that a properly qualified name is set in __qualname__ and that
    generated docstrings properly use it and the module name"""
    assert m.NestBase.__qualname__ == "NestBase"
    assert m.NestBase.Nested.__qualname__ == "NestBase.Nested"

    assert (
        doc(m.NestBase.__init__)
        == """
        __init__(self: m.class_.NestBase) -> None
    """
    )
    assert (
        doc(m.NestBase.g)
        == """
        g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None
    """
    )
    assert (
        doc(m.NestBase.Nested.__init__)
        == """
        __init__(self: m.class_.NestBase.Nested) -> None
    """
    )
    assert (
        doc(m.NestBase.Nested.fn)
        == """
        fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
    """
    )
    assert (
        doc(m.NestBase.Nested.fa)
        == """
        fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
    """
    )
    assert m.NestBase.__module__ == "pybind11_tests.class_"
    assert m.NestBase.Nested.__module__ == "pybind11_tests.class_"


def test_inheritance(msg):
    roger = m.Rabbit("Rabbit")
    assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot"
    assert m.pet_name_species(roger) == "Rabbit is a parrot"

    polly = m.Pet("Polly", "parrot")
    assert polly.name() + " is a " + polly.species() == "Polly is a parrot"
    assert m.pet_name_species(polly) == "Polly is a parrot"

    molly = m.Dog("Molly")
    assert molly.name() + " is a " + molly.species() == "Molly is a dog"
    assert m.pet_name_species(molly) == "Molly is a dog"

    fred = m.Hamster("Fred")
    assert fred.name() + " is a " + fred.species() == "Fred is a rodent"

    assert m.dog_bark(molly) == "Woof!"

    with pytest.raises(TypeError) as excinfo:
        m.dog_bark(polly)
    assert (
        msg(excinfo.value)
        == """
        dog_bark(): incompatible function arguments. The following argument types are supported:
            1. (arg0: m.class_.Dog) -> str

        Invoked with: <m.class_.Pet object at 0>
    """
    )

    with pytest.raises(TypeError) as excinfo:
        m.Chimera("lion", "goat")
    assert "No constructor defined!" in str(excinfo.value)


def test_inheritance_init(msg):
    # Single base
    class Python(m.Pet):
        def __init__(self):
            pass

    with pytest.raises(TypeError) as exc_info:
        Python()
    expected = "m.class_.Pet.__init__() must be called when overriding __init__"
    assert msg(exc_info.value) == expected

    # Multiple bases
    class RabbitHamster(m.Rabbit, m.Hamster):
        def __init__(self):
            m.Rabbit.__init__(self, "RabbitHamster")

    with pytest.raises(TypeError) as exc_info:
        RabbitHamster()
    expected = "m.class_.Hamster.__init__() must be called when overriding __init__"
    assert msg(exc_info.value) == expected


def test_automatic_upcasting():
    assert type(m.return_class_1()).__name__ == "DerivedClass1"
    assert type(m.return_class_2()).__name__ == "DerivedClass2"
    assert type(m.return_none()).__name__ == "NoneType"
    # Repeat these a few times in a random order to ensure no invalid caching is applied
    assert type(m.return_class_n(1)).__name__ == "DerivedClass1"
    assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
    assert type(m.return_class_n(0)).__name__ == "BaseClass"
    assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
    assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
    assert type(m.return_class_n(0)).__name__ == "BaseClass"
    assert type(m.return_class_n(1)).__name__ == "DerivedClass1"


def test_isinstance():
    objects = [(), {}, m.Pet("Polly", "parrot")] + [m.Dog("Molly")] * 4
    expected = (True, True, True, True, True, False, False)
    assert m.check_instances(objects) == expected


def test_mismatched_holder():
    import re

    with pytest.raises(RuntimeError) as excinfo:
        m.mismatched_holder_1()
    assert re.match(
        'generic_type: type ".*MismatchDerived1" does not have a non-default '
        'holder type while its base ".*MismatchBase1" does',
        str(excinfo.value),
    )

    with pytest.raises(RuntimeError) as excinfo:
        m.mismatched_holder_2()
    assert re.match(
        'generic_type: type ".*MismatchDerived2" has a non-default holder type '
        'while its base ".*MismatchBase2" does not',
        str(excinfo.value),
    )


def test_override_static():
    """#511: problem with inheritance + overwritten def_static"""
    b = m.MyBase.make()
    d1 = m.MyDerived.make2()
    d2 = m.MyDerived.make()

    assert isinstance(b, m.MyBase)
    assert isinstance(d1, m.MyDerived)
    assert isinstance(d2, m.MyDerived)


def test_implicit_conversion_life_support():
    """Ensure the lifetime of temporary objects created for implicit conversions"""
    assert m.implicitly_convert_argument(UserType(5)) == 5
    assert m.implicitly_convert_variable(UserType(5)) == 5

    assert "outside a bound function" in m.implicitly_convert_variable_fail(UserType(5))


def test_operator_new_delete(capture):
    """Tests that class-specific operator new/delete functions are invoked"""

    class SubAliased(m.AliasedHasOpNewDelSize):
        pass

    with capture:
        a = m.HasOpNewDel()
        b = m.HasOpNewDelSize()
        d = m.HasOpNewDelBoth()
    assert (
        capture
        == """
        A new 8
        B new 4
        D new 32
    """
    )
    sz_alias = str(m.AliasedHasOpNewDelSize.size_alias)
    sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias)
    with capture:
        c = m.AliasedHasOpNewDelSize()
        c2 = SubAliased()
    assert capture == ("C new " + sz_noalias + "\n" + "C new " + sz_alias + "\n")

    with capture:
        del a
        pytest.gc_collect()
        del b
        pytest.gc_collect()
        del d
        pytest.gc_collect()
    assert (
        capture
        == """
        A delete
        B delete 4
        D delete
    """
    )

    with capture:
        del c
        pytest.gc_collect()
        del c2
        pytest.gc_collect()
    assert capture == ("C delete " + sz_noalias + "\n" + "C delete " + sz_alias + "\n")


def test_bind_protected_functions():
    """Expose protected member functions to Python using a helper class"""
    a = m.ProtectedA()
    assert a.foo() == 42

    b = m.ProtectedB()
    assert b.foo() == 42
    assert m.read_foo(b.void_foo()) == 42
    assert m.pointers_equal(b.get_self(), b)

    class C(m.ProtectedB):
        def __init__(self):
            m.ProtectedB.__init__(self)

        def foo(self):
            return 0

    c = C()
    assert c.foo() == 0


def test_brace_initialization():
    """Tests that simple POD classes can be constructed using C++11 brace initialization"""
    a = m.BraceInitialization(123, "test")
    assert a.field1 == 123
    assert a.field2 == "test"

    # Tests that a non-simple class doesn't get brace initialization (if the
    # class defines an initializer_list constructor, in particular, it would
    # win over the expected constructor).
    b = m.NoBraceInitialization([123, 456])
    assert b.vec == [123, 456]


@pytest.mark.xfail("env.PYPY")
def test_class_refcount():
    """Instances must correctly increase/decrease the reference count of their types (#1029)"""
    from sys import getrefcount

    class PyDog(m.Dog):
        pass

    for cls in m.Dog, PyDog:
        refcount_1 = getrefcount(cls)
        molly = [cls("Molly") for _ in range(10)]
        refcount_2 = getrefcount(cls)

        del molly
        pytest.gc_collect()
        refcount_3 = getrefcount(cls)

        assert refcount_1 == refcount_3
        assert refcount_2 > refcount_1


def test_reentrant_implicit_conversion_failure(msg):
    # ensure that there is no runaway reentrant implicit conversion (#1035)
    with pytest.raises(TypeError) as excinfo:
        m.BogusImplicitConversion(0)
    assert (
        msg(excinfo.value)
        == """
        __init__(): incompatible constructor arguments. The following argument types are supported:
            1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)

        Invoked with: 0
    """
    )


def test_error_after_conversions():
    with pytest.raises(TypeError) as exc_info:
        m.test_error_after_conversions("hello")
    assert str(exc_info.value).startswith(
        "Unable to convert function return value to a Python type!"
    )


def test_aligned():
    if hasattr(m, "Aligned"):
        p = m.Aligned().ptr()
        assert p % 1024 == 0


# https://foss.heptapod.net/pypy/pypy/-/issues/2742
@pytest.mark.xfail("env.PYPY")
def test_final():
    with pytest.raises(TypeError) as exc_info:

        class PyFinalChild(m.IsFinal):
            pass

    assert str(exc_info.value).endswith("is not an acceptable base type")


# https://foss.heptapod.net/pypy/pypy/-/issues/2742
@pytest.mark.xfail("env.PYPY")
def test_non_final_final():
    with pytest.raises(TypeError) as exc_info:

        class PyNonFinalFinalChild(m.IsNonFinalFinal):
            pass

    assert str(exc_info.value).endswith("is not an acceptable base type")


# https://github.com/pybind/pybind11/issues/1878
def test_exception_rvalue_abort():
    with pytest.raises(RuntimeError):
        m.PyPrintDestructor().throw_something()


# https://github.com/pybind/pybind11/issues/1568
def test_multiple_instances_with_same_pointer():
    n = 100
    instances = [m.SamePointer() for _ in range(n)]
    for i in range(n):
        # We need to reuse the same allocated memory for with a different type,
        # to ensure the bug in `deregister_instance_impl` is detected. Otherwise
        # `Py_TYPE(self) == Py_TYPE(it->second)` will still succeed, even though
        # the `instance` is already deleted.
        instances[i] = m.Empty()
    # No assert: if this does not trigger the error
    #   pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
    # and just completes without crashing, we're good.


# https://github.com/pybind/pybind11/issues/1624
def test_base_and_derived_nested_scope():
    assert issubclass(m.DerivedWithNested, m.BaseWithNested)
    assert m.BaseWithNested.Nested != m.DerivedWithNested.Nested
    assert m.BaseWithNested.Nested.get_name() == "BaseWithNested::Nested"
    assert m.DerivedWithNested.Nested.get_name() == "DerivedWithNested::Nested"


def test_register_duplicate_class():
    import types

    module_scope = types.ModuleType("module_scope")
    with pytest.raises(RuntimeError) as exc_info:
        m.register_duplicate_class_name(module_scope)
    expected = (
        'generic_type: cannot initialize type "Duplicate": '
        "an object with that name is already defined"
    )
    assert str(exc_info.value) == expected
    with pytest.raises(RuntimeError) as exc_info:
        m.register_duplicate_class_type(module_scope)
    expected = 'generic_type: type "YetAnotherDuplicate" is already registered!'
    assert str(exc_info.value) == expected

    class ClassScope:
        pass

    with pytest.raises(RuntimeError) as exc_info:
        m.register_duplicate_nested_class_name(ClassScope)
    expected = (
        'generic_type: cannot initialize type "DuplicateNested": '
        "an object with that name is already defined"
    )
    assert str(exc_info.value) == expected
    with pytest.raises(RuntimeError) as exc_info:
        m.register_duplicate_nested_class_type(ClassScope)
    expected = 'generic_type: type "YetAnotherDuplicateNested" is already registered!'
    assert str(exc_info.value) == expected


def test_pr4220_tripped_over_this():
    assert (
        m.Empty0().get_msg()
        == "This is really only meant to exercise successful compilation."
    )
