/*
    tests/test_class.cpp -- test py::class_ definitions and basic functionality

    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#if defined(__INTEL_COMPILER) && __cplusplus >= 201703L
// Intel compiler requires a separate header file to support aligned new operators
// and does not set the __cpp_aligned_new feature macro.
// This header needs to be included before pybind11.
#include <aligned_new>
#endif

#include "pybind11_tests.h"
#include "constructor_stats.h"
#include "local_bindings.h"
#include <pybind11/stl.h>

#if defined(_MSC_VER)
#  pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier
#endif

// test_brace_initialization
struct NoBraceInitialization {
    NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}
    template <typename T>
    NoBraceInitialization(std::initializer_list<T> l) : vec(l) {}

    std::vector<int> vec;
};

TEST_SUBMODULE(class_, m) {
    // test_instance
    struct NoConstructor {
        NoConstructor() = default;
        NoConstructor(const NoConstructor &) = default;
        NoConstructor(NoConstructor &&) = default;
        static NoConstructor *new_instance() {
            auto *ptr = new NoConstructor();
            print_created(ptr, "via new_instance");
            return ptr;
        }
        ~NoConstructor() { print_destroyed(this); }
    };

    py::class_<NoConstructor>(m, "NoConstructor")
        .def_static("new_instance", &NoConstructor::new_instance, "Return an instance");

    // test_inheritance
    class Pet {
    public:
        Pet(const std::string &name, const std::string &species)
            : m_name(name), m_species(species) {}
        std::string name() const { return m_name; }
        std::string species() const { return m_species; }
    private:
        std::string m_name;
        std::string m_species;
    };

    class Dog : public Pet {
    public:
        Dog(const std::string &name) : Pet(name, "dog") {}
        std::string bark() const { return "Woof!"; }
    };

    class Rabbit : public Pet {
    public:
        Rabbit(const std::string &name) : Pet(name, "parrot") {}
    };

    class Hamster : public Pet {
    public:
        Hamster(const std::string &name) : Pet(name, "rodent") {}
    };

    class Chimera : public Pet {
        Chimera() : Pet("Kimmy", "chimera") {}
    };

    py::class_<Pet> pet_class(m, "Pet");
    pet_class
        .def(py::init<std::string, std::string>())
        .def("name", &Pet::name)
        .def("species", &Pet::species);

    /* One way of declaring a subclass relationship: reference parent's class_ object */
    py::class_<Dog>(m, "Dog", pet_class)
        .def(py::init<std::string>());

    /* Another way of declaring a subclass relationship: reference parent's C++ type */
    py::class_<Rabbit, Pet>(m, "Rabbit")
        .def(py::init<std::string>());

    /* And another: list parent in class template arguments */
    py::class_<Hamster, Pet>(m, "Hamster")
        .def(py::init<std::string>());

    /* Constructors are not inherited by default */
    py::class_<Chimera, Pet>(m, "Chimera");

    m.def("pet_name_species", [](const Pet &pet) { return pet.name() + " is a " + pet.species(); });
    m.def("dog_bark", [](const Dog &dog) { return dog.bark(); });

    // test_automatic_upcasting
    struct BaseClass {
        BaseClass() = default;
        BaseClass(const BaseClass &) = default;
        BaseClass(BaseClass &&) = default;
        virtual ~BaseClass() = default;
    };
    struct DerivedClass1 : BaseClass { };
    struct DerivedClass2 : BaseClass { };

    py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
    py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>());
    py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>());

    m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); });
    m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); });
    m.def("return_class_n", [](int n) -> BaseClass* {
        if (n == 1) return new DerivedClass1();
        if (n == 2) return new DerivedClass2();
        return new BaseClass();
    });
    m.def("return_none", []() -> BaseClass* { return nullptr; });

    // test_isinstance
    m.def("check_instances", [](py::list l) {
        return py::make_tuple(
            py::isinstance<py::tuple>(l[0]),
            py::isinstance<py::dict>(l[1]),
            py::isinstance<Pet>(l[2]),
            py::isinstance<Pet>(l[3]),
            py::isinstance<Dog>(l[4]),
            py::isinstance<Rabbit>(l[5]),
            py::isinstance<UnregisteredType>(l[6])
        );
    });

    struct Invalid {};

    // test_type
    m.def("check_type", [](int category) {
        // Currently not supported (via a fail at compile time)
        // See https://github.com/pybind/pybind11/issues/2486
        // if (category == 2)
        //     return py::type::of<int>();
        if (category == 1)
            return py::type::of<DerivedClass1>();
        else
            return py::type::of<Invalid>();
    });

    m.def("get_type_of", [](py::object ob) {
        return py::type::of(ob);
    });

    m.def("get_type_classic", [](py::handle h) {
        return h.get_type();
    });

    m.def("as_type", [](py::object ob) {
        return py::type(ob);
    });

    // test_mismatched_holder
    struct MismatchBase1 { };
    struct MismatchDerived1 : MismatchBase1 { };

    struct MismatchBase2 { };
    struct MismatchDerived2 : MismatchBase2 { };

    m.def("mismatched_holder_1", []() {
        auto mod = py::module_::import("__main__");
        py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1");
        py::class_<MismatchDerived1, MismatchBase1>(mod, "MismatchDerived1");
    });
    m.def("mismatched_holder_2", []() {
        auto mod = py::module_::import("__main__");
        py::class_<MismatchBase2>(mod, "MismatchBase2");
        py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>,
                   MismatchBase2>(mod, "MismatchDerived2");
    });

    // test_override_static
    // #511: problem with inheritance + overwritten def_static
    struct MyBase {
        static std::unique_ptr<MyBase> make() {
            return std::unique_ptr<MyBase>(new MyBase());
        }
    };

    struct MyDerived : MyBase {
        static std::unique_ptr<MyDerived> make() {
            return std::unique_ptr<MyDerived>(new MyDerived());
        }
    };

    py::class_<MyBase>(m, "MyBase")
        .def_static("make", &MyBase::make);

    py::class_<MyDerived, MyBase>(m, "MyDerived")
        .def_static("make", &MyDerived::make)
        .def_static("make2", &MyDerived::make);

    // test_implicit_conversion_life_support
    struct ConvertibleFromUserType {
        int i;

        ConvertibleFromUserType(UserType u) : i(u.value()) { }
    };

    py::class_<ConvertibleFromUserType>(m, "AcceptsUserType")
        .def(py::init<UserType>());
    py::implicitly_convertible<UserType, ConvertibleFromUserType>();

    m.def("implicitly_convert_argument", [](const ConvertibleFromUserType &r) { return r.i; });
    m.def("implicitly_convert_variable", [](py::object o) {
        // `o` is `UserType` and `r` is a reference to a temporary created by implicit
        // conversion. This is valid when called inside a bound function because the temp
        // object is attached to the same life support system as the arguments.
        const auto &r = o.cast<const ConvertibleFromUserType &>();
        return r.i;
    });
    m.add_object("implicitly_convert_variable_fail", [&] {
        auto f = [](PyObject *, PyObject *args) -> PyObject * {
            auto o = py::reinterpret_borrow<py::tuple>(args)[0];
            try { // It should fail here because there is no life support.
                o.cast<const ConvertibleFromUserType &>();
            } catch (const py::cast_error &e) {
                return py::str(e.what()).release().ptr();
            }
            return py::str().release().ptr();
        };

        auto def = new PyMethodDef{"f", f, METH_VARARGS, nullptr};
        py::capsule def_capsule(def, [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); });
        return py::reinterpret_steal<py::object>(PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr()));
    }());

    // test_operator_new_delete
    struct HasOpNewDel {
        std::uint64_t i;
        static void *operator new(size_t s) { py::print("A new", s); return ::operator new(s); }
        static void *operator new(size_t s, void *ptr) { py::print("A placement-new", s); return ptr; }
        static void operator delete(void *p) { py::print("A delete"); return ::operator delete(p); }
    };
    struct HasOpNewDelSize {
        std::uint32_t i;
        static void *operator new(size_t s) { py::print("B new", s); return ::operator new(s); }
        static void *operator new(size_t s, void *ptr) { py::print("B placement-new", s); return ptr; }
        static void operator delete(void *p, size_t s) { py::print("B delete", s); return ::operator delete(p); }
    };
    struct AliasedHasOpNewDelSize {
        std::uint64_t i;
        static void *operator new(size_t s) { py::print("C new", s); return ::operator new(s); }
        static void *operator new(size_t s, void *ptr) { py::print("C placement-new", s); return ptr; }
        static void operator delete(void *p, size_t s) { py::print("C delete", s); return ::operator delete(p); }
        virtual ~AliasedHasOpNewDelSize() = default;
        AliasedHasOpNewDelSize() = default;
        AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize&) = delete;
    };
    struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize {
        PyAliasedHasOpNewDelSize() = default;
        PyAliasedHasOpNewDelSize(int) { }
        std::uint64_t j;
    };
    struct HasOpNewDelBoth {
        std::uint32_t i[8];
        static void *operator new(size_t s) { py::print("D new", s); return ::operator new(s); }
        static void *operator new(size_t s, void *ptr) { py::print("D placement-new", s); return ptr; }
        static void operator delete(void *p) { py::print("D delete"); return ::operator delete(p); }
        static void operator delete(void *p, size_t s) { py::print("D wrong delete", s); return ::operator delete(p); }
    };
    py::class_<HasOpNewDel>(m, "HasOpNewDel").def(py::init<>());
    py::class_<HasOpNewDelSize>(m, "HasOpNewDelSize").def(py::init<>());
    py::class_<HasOpNewDelBoth>(m, "HasOpNewDelBoth").def(py::init<>());
    py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m, "AliasedHasOpNewDelSize");
    aliased.def(py::init<>());
    aliased.attr("size_noalias") = py::int_(sizeof(AliasedHasOpNewDelSize));
    aliased.attr("size_alias") = py::int_(sizeof(PyAliasedHasOpNewDelSize));

    // This test is actually part of test_local_bindings (test_duplicate_local), but we need a
    // definition in a different compilation unit within the same module:
    bind_local<LocalExternal, 17>(m, "LocalExternal", py::module_local());

    // test_bind_protected_functions
    class ProtectedA {
    protected:
        int foo() const { return value; }

    private:
        int value = 42;
    };

    class PublicistA : public ProtectedA {
    public:
        using ProtectedA::foo;
    };

    py::class_<ProtectedA>(m, "ProtectedA")
        .def(py::init<>())
#if !defined(_MSC_VER) || _MSC_VER >= 1910
        .def("foo", &PublicistA::foo);
#else
        .def("foo", static_cast<int (ProtectedA::*)() const>(&PublicistA::foo));
#endif

    class ProtectedB {
    public:
        virtual ~ProtectedB() = default;
        ProtectedB() = default;
        ProtectedB(const ProtectedB &) = delete;

    protected:
        virtual int foo() const { return value; }

    private:
        int value = 42;
    };

    class TrampolineB : public ProtectedB {
    public:
        int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }
    };

    class PublicistB : public ProtectedB {
    public:
        // [workaround(intel)] = default does not work here
        // Removing or defaulting this destructor results in linking errors with the Intel compiler
        // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)
        ~PublicistB() override {};  // NOLINT(modernize-use-equals-default)
        using ProtectedB::foo;
    };

    py::class_<ProtectedB, TrampolineB>(m, "ProtectedB")
        .def(py::init<>())
#if !defined(_MSC_VER) || _MSC_VER >= 1910
        .def("foo", &PublicistB::foo);
#else
        .def("foo", static_cast<int (ProtectedB::*)() const>(&PublicistB::foo));
#endif

    // test_brace_initialization
    struct BraceInitialization {
        int field1;
        std::string field2;
    };

    py::class_<BraceInitialization>(m, "BraceInitialization")
        .def(py::init<int, const std::string &>())
        .def_readwrite("field1", &BraceInitialization::field1)
        .def_readwrite("field2", &BraceInitialization::field2);
    // We *don't* want to construct using braces when the given constructor argument maps to a
    // constructor, because brace initialization could go to the wrong place (in particular when
    // there is also an `initializer_list<T>`-accept constructor):
    py::class_<NoBraceInitialization>(m, "NoBraceInitialization")
        .def(py::init<std::vector<int>>())
        .def_readonly("vec", &NoBraceInitialization::vec);

    // test_reentrant_implicit_conversion_failure
    // #1035: issue with runaway reentrant implicit conversion
    struct BogusImplicitConversion {
        BogusImplicitConversion(const BogusImplicitConversion &) = default;
    };

    py::class_<BogusImplicitConversion>(m, "BogusImplicitConversion")
        .def(py::init<const BogusImplicitConversion &>());

    py::implicitly_convertible<int, BogusImplicitConversion>();

    // test_qualname
    // #1166: nested class docstring doesn't show nested name
    // Also related: tests that __qualname__ is set properly
    struct NestBase {};
    struct Nested {};
    py::class_<NestBase> base(m, "NestBase");
    base.def(py::init<>());
    py::class_<Nested>(base, "Nested")
        .def(py::init<>())
        .def("fn", [](Nested &, int, NestBase &, Nested &) {})
        .def("fa", [](Nested &, int, NestBase &, Nested &) {},
                "a"_a, "b"_a, "c"_a);
    base.def("g", [](NestBase &, Nested &) {});
    base.def("h", []() { return NestBase(); });

    // test_error_after_conversion
    // The second-pass path through dispatcher() previously didn't
    // remember which overload was used, and would crash trying to
    // generate a useful error message

    struct NotRegistered {};
    struct StringWrapper { std::string str; };
    m.def("test_error_after_conversions", [](int) {});
    m.def("test_error_after_conversions",
          [](StringWrapper) -> NotRegistered { return {}; });
    py::class_<StringWrapper>(m, "StringWrapper").def(py::init<std::string>());
    py::implicitly_convertible<std::string, StringWrapper>();

    #if defined(PYBIND11_CPP17)
        struct alignas(1024) Aligned {
            std::uintptr_t ptr() const { return (uintptr_t) this; }
        };
        py::class_<Aligned>(m, "Aligned")
            .def(py::init<>())
            .def("ptr", &Aligned::ptr);
    #endif

    // test_final
    struct IsFinal final {};
    py::class_<IsFinal>(m, "IsFinal", py::is_final());

    // test_non_final_final
    struct IsNonFinalFinal {};
    py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final());

    // test_exception_rvalue_abort
    struct PyPrintDestructor {
        PyPrintDestructor() = default;
        ~PyPrintDestructor() {
            py::print("Print from destructor");
        }
        void throw_something() { throw std::runtime_error("error"); }
    };
    py::class_<PyPrintDestructor>(m, "PyPrintDestructor")
        .def(py::init<>())
        .def("throw_something", &PyPrintDestructor::throw_something);

    // test_multiple_instances_with_same_pointer
    struct SamePointer {};
    static SamePointer samePointer;
    py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, "SamePointer")
        .def(py::init([]() { return &samePointer; }))
        .def("__del__", [](SamePointer&) { py::print("__del__ called"); });

    struct Empty {};
    py::class_<Empty>(m, "Empty")
        .def(py::init<>());

    // test_base_and_derived_nested_scope
    struct BaseWithNested {
        struct Nested {};
    };

    struct DerivedWithNested : BaseWithNested {
        struct Nested {};
    };

    py::class_<BaseWithNested> baseWithNested_class(m, "BaseWithNested");
    py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, "DerivedWithNested");
    py::class_<BaseWithNested::Nested>(baseWithNested_class, "Nested")
        .def_static("get_name", []() { return "BaseWithNested::Nested"; });
    py::class_<DerivedWithNested::Nested>(derivedWithNested_class, "Nested")
        .def_static("get_name", []() { return "DerivedWithNested::Nested"; });

    // test_register_duplicate_class
    struct Duplicate {};
    struct OtherDuplicate {};
    struct DuplicateNested {};
    struct OtherDuplicateNested {};
    m.def("register_duplicate_class_name", [](py::module_ m) {
        py::class_<Duplicate>(m, "Duplicate");
        py::class_<OtherDuplicate>(m, "Duplicate");
    });
    m.def("register_duplicate_class_type", [](py::module_ m) {
        py::class_<OtherDuplicate>(m, "OtherDuplicate");
        py::class_<OtherDuplicate>(m, "YetAnotherDuplicate");
    });
    m.def("register_duplicate_nested_class_name", [](py::object gt) {
        py::class_<DuplicateNested>(gt, "DuplicateNested");
        py::class_<OtherDuplicateNested>(gt, "DuplicateNested");
    });
    m.def("register_duplicate_nested_class_type", [](py::object gt) {
        py::class_<OtherDuplicateNested>(gt, "OtherDuplicateNested");
        py::class_<OtherDuplicateNested>(gt, "YetAnotherDuplicateNested");
    });
}

template <int N> class BreaksBase { public:
    virtual ~BreaksBase() = default;
    BreaksBase() = default;
    BreaksBase(const BreaksBase&) = delete;
};
template <int N> class BreaksTramp : public BreaksBase<N> {};
// These should all compile just fine:
using DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>;
using DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>;
using DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>;
using DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>;
using DoesntBreak5 = py::class_<BreaksBase<5>>;
using DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>;
using DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>;
using DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>;
#define CHECK_BASE(N) static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<N>>::value, \
        "DoesntBreak" #N " has wrong type!")
CHECK_BASE(1); CHECK_BASE(2); CHECK_BASE(3); CHECK_BASE(4); CHECK_BASE(5); CHECK_BASE(6); CHECK_BASE(7); CHECK_BASE(8);
#define CHECK_ALIAS(N) static_assert(DoesntBreak##N::has_alias && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<N>>::value, \
        "DoesntBreak" #N " has wrong type_alias!")
#define CHECK_NOALIAS(N) static_assert(!DoesntBreak##N::has_alias && std::is_void<typename DoesntBreak##N::type_alias>::value, \
        "DoesntBreak" #N " has type alias, but shouldn't!")
CHECK_ALIAS(1); CHECK_ALIAS(2); CHECK_NOALIAS(3); CHECK_ALIAS(4); CHECK_NOALIAS(5); CHECK_ALIAS(6); CHECK_ALIAS(7); CHECK_NOALIAS(8);
#define CHECK_HOLDER(N, TYPE) static_assert(std::is_same<typename DoesntBreak##N::holder_type, std::TYPE##_ptr<BreaksBase<N>>>::value, \
        "DoesntBreak" #N " has wrong holder_type!")
CHECK_HOLDER(1, unique); CHECK_HOLDER(2, unique); CHECK_HOLDER(3, unique); CHECK_HOLDER(4, unique); CHECK_HOLDER(5, unique);
CHECK_HOLDER(6, shared); CHECK_HOLDER(7, shared); CHECK_HOLDER(8, shared);

// There's no nice way to test that these fail because they fail to compile; leave them here,
// though, so that they can be manually tested by uncommenting them (and seeing that compilation
// failures occurs).

// We have to actually look into the type: the typedef alone isn't enough to instantiate the type:
#define CHECK_BROKEN(N) static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-N>>::value, \
        "Breaks1 has wrong type!");

//// Two holder classes:
//typedef py::class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>> Breaks1;
//CHECK_BROKEN(1);
//// Two aliases:
//typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;
//CHECK_BROKEN(2);
//// Holder + 2 aliases
//typedef py::class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3;
//CHECK_BROKEN(3);
//// Alias + 2 holders
//typedef py::class_<BreaksBase<-4>, std::unique_ptr<BreaksBase<-4>>, BreaksTramp<-4>, std::shared_ptr<BreaksBase<-4>>> Breaks4;
//CHECK_BROKEN(4);
//// Invalid option (not a subclass or holder)
//typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;
//CHECK_BROKEN(5);
//// Invalid option: multiple inheritance not supported:
//template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};
//typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;
//CHECK_BROKEN(8);
