/*
    tests/test_smart_ptr.cpp -- binding classes with custom reference counting,
    implicit conversions between types

    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.
*/

#include "object.h"
#include "pybind11_tests.h"

namespace {

// This is just a wrapper around unique_ptr, but with extra fields to deliberately bloat up the
// holder size to trigger the non-simple-layout internal instance layout for single inheritance
// with large holder type:
template <typename T>
class huge_unique_ptr {
    std::unique_ptr<T> ptr;
    uint64_t padding[10];

public:
    explicit huge_unique_ptr(T *p) : ptr(p) {}
    T *get() { return ptr.get(); }
};

// Simple custom holder that works like unique_ptr
template <typename T>
class custom_unique_ptr {
    std::unique_ptr<T> impl;

public:
    explicit custom_unique_ptr(T *p) : impl(p) {}
    T *get() const { return impl.get(); }
    T *release_ptr() { return impl.release(); }
};

// Simple custom holder that works like shared_ptr and has operator& overload
// To obtain address of an instance of this holder pybind should use std::addressof
// Attempt to get address via operator& may leads to segmentation fault
template <typename T>
class shared_ptr_with_addressof_operator {
    std::shared_ptr<T> impl;

public:
    shared_ptr_with_addressof_operator() = default;
    explicit shared_ptr_with_addressof_operator(T *p) : impl(p) {}
    T *get() const { return impl.get(); }
    T **operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); }
};

// Simple custom holder that works like unique_ptr and has operator& overload
// To obtain address of an instance of this holder pybind should use std::addressof
// Attempt to get address via operator& may leads to segmentation fault
template <typename T>
class unique_ptr_with_addressof_operator {
    std::unique_ptr<T> impl;

public:
    unique_ptr_with_addressof_operator() = default;
    explicit unique_ptr_with_addressof_operator(T *p) : impl(p) {}
    T *get() const { return impl.get(); }
    T *release_ptr() { return impl.release(); }
    T **operator&() { throw std::logic_error("Call of overloaded operator& is not expected"); }
};

// Custom object with builtin reference counting (see 'object.h' for the implementation)
class MyObject1 : public Object {
public:
    explicit MyObject1(int value) : value(value) { print_created(this, toString()); }
    std::string toString() const override { return "MyObject1[" + std::to_string(value) + "]"; }

protected:
    ~MyObject1() override { print_destroyed(this); }

private:
    int value;
};

// Object managed by a std::shared_ptr<>
class MyObject2 {
public:
    MyObject2(const MyObject2 &) = default;
    explicit MyObject2(int value) : value(value) { print_created(this, toString()); }
    std::string toString() const { return "MyObject2[" + std::to_string(value) + "]"; }
    virtual ~MyObject2() { print_destroyed(this); }

private:
    int value;
};

// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<>
class MyObject3 : public std::enable_shared_from_this<MyObject3> {
public:
    MyObject3(const MyObject3 &) = default;
    explicit MyObject3(int value) : value(value) { print_created(this, toString()); }
    std::string toString() const { return "MyObject3[" + std::to_string(value) + "]"; }
    virtual ~MyObject3() { print_destroyed(this); }

private:
    int value;
};

// test_unique_nodelete
// Object with a private destructor
class MyObject4;
std::unordered_set<MyObject4 *> myobject4_instances;
class MyObject4 {
public:
    explicit MyObject4(int value) : value{value} {
        print_created(this);
        myobject4_instances.insert(this);
    }
    int value;

    static void cleanupAllInstances() {
        auto tmp = std::move(myobject4_instances);
        myobject4_instances.clear();
        for (auto *o : tmp) {
            delete o;
        }
    }

private:
    ~MyObject4() {
        myobject4_instances.erase(this);
        print_destroyed(this);
    }
};

// test_unique_deleter
// Object with std::unique_ptr<T, D> where D is not matching the base class
// Object with a protected destructor
class MyObject4a;
std::unordered_set<MyObject4a *> myobject4a_instances;
class MyObject4a {
public:
    explicit MyObject4a(int i) : value{i} {
        print_created(this);
        myobject4a_instances.insert(this);
    };
    int value;

    static void cleanupAllInstances() {
        auto tmp = std::move(myobject4a_instances);
        myobject4a_instances.clear();
        for (auto *o : tmp) {
            delete o;
        }
    }

protected:
    virtual ~MyObject4a() {
        myobject4a_instances.erase(this);
        print_destroyed(this);
    }
};

// Object derived but with public destructor and no Deleter in default holder
class MyObject4b : public MyObject4a {
public:
    explicit MyObject4b(int i) : MyObject4a(i) { print_created(this); }
    ~MyObject4b() override { print_destroyed(this); }
};

// test_large_holder
class MyObject5 { // managed by huge_unique_ptr
public:
    explicit MyObject5(int value) : value{value} { print_created(this); }
    ~MyObject5() { print_destroyed(this); }
    int value;
};

// test_shared_ptr_and_references
struct SharedPtrRef {
    struct A {
        A() { print_created(this); }
        A(const A &) { print_copy_created(this); }
        A(A &&) noexcept { print_move_created(this); }
        ~A() { print_destroyed(this); }
    };

    A value = {};
    std::shared_ptr<A> shared = std::make_shared<A>();
};

// test_shared_ptr_from_this_and_references
struct SharedFromThisRef {
    struct B : std::enable_shared_from_this<B> {
        B() { print_created(this); }
        // NOLINTNEXTLINE(bugprone-copy-constructor-init)
        B(const B &) : std::enable_shared_from_this<B>() { print_copy_created(this); }
        B(B &&) noexcept : std::enable_shared_from_this<B>() { print_move_created(this); }
        ~B() { print_destroyed(this); }
    };

    B value = {};
    std::shared_ptr<B> shared = std::make_shared<B>();
};

// Issue #865: shared_from_this doesn't work with virtual inheritance
struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
    SharedFromThisVBase() = default;
    SharedFromThisVBase(const SharedFromThisVBase &) = default;
    virtual ~SharedFromThisVBase() = default;
};
struct SharedFromThisVirt : virtual SharedFromThisVBase {};

// test_move_only_holder
struct C {
    C() { print_created(this); }
    ~C() { print_destroyed(this); }
};

// test_holder_with_addressof_operator
struct TypeForHolderWithAddressOf {
    TypeForHolderWithAddressOf() { print_created(this); }
    TypeForHolderWithAddressOf(const TypeForHolderWithAddressOf &) { print_copy_created(this); }
    TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {
        print_move_created(this);
    }
    ~TypeForHolderWithAddressOf() { print_destroyed(this); }
    std::string toString() const {
        return "TypeForHolderWithAddressOf[" + std::to_string(value) + "]";
    }
    int value = 42;
};

// test_move_only_holder_with_addressof_operator
struct TypeForMoveOnlyHolderWithAddressOf {
    explicit TypeForMoveOnlyHolderWithAddressOf(int value) : value{value} { print_created(this); }
    ~TypeForMoveOnlyHolderWithAddressOf() { print_destroyed(this); }
    std::string toString() const {
        return "MoveOnlyHolderWithAddressOf[" + std::to_string(value) + "]";
    }
    int value;
};

// test_smart_ptr_from_default
struct HeldByDefaultHolder {};

// test_shared_ptr_gc
// #187: issue involving std::shared_ptr<> return value policy & garbage collection
struct ElementBase {
    virtual ~ElementBase() = default; /* Force creation of virtual table */
    ElementBase() = default;
    ElementBase(const ElementBase &) = delete;
};

struct ElementA : ElementBase {
    explicit ElementA(int v) : v(v) {}
    int value() const { return v; }
    int v;
};

struct ElementList {
    void add(const std::shared_ptr<ElementBase> &e) { l.push_back(e); }
    std::vector<std::shared_ptr<ElementBase>> l;
};

} // namespace

// ref<T> is a wrapper for 'Object' which uses intrusive reference counting
// It is always possible to construct a ref<T> from an Object* pointer without
// possible inconsistencies, hence the 'true' argument at the end.
// Make pybind11 aware of the non-standard getter member function
namespace PYBIND11_NAMESPACE {
namespace detail {
template <typename T>
struct holder_helper<ref<T>> {
    static const T *get(const ref<T> &p) { return p.get_ptr(); }
};
} // namespace detail
} // namespace PYBIND11_NAMESPACE

// Make pybind aware of the ref-counted wrapper type (s):
PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true);
// The following is not required anymore for std::shared_ptr, but it should compile without error:
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>);

TEST_SUBMODULE(smart_ptr, m) {
    // Please do not interleave `struct` and `class` definitions with bindings code,
    // but implement `struct`s and `class`es in the anonymous namespace above.
    // This helps keeping the smart_holder branch in sync with master.

    // test_smart_ptr

    // Object implementation in `object.h`
    py::class_<Object, ref<Object>> obj(m, "Object");
    obj.def("getRefCount", &Object::getRefCount);

    py::class_<MyObject1, ref<MyObject1>>(m, "MyObject1", obj).def(py::init<int>());
    py::implicitly_convertible<py::int_, MyObject1>();

    m.def("make_object_1", []() -> Object * { return new MyObject1(1); });
    m.def("make_object_2", []() -> ref<Object> { return ref<Object>(new MyObject1(2)); });
    m.def("make_myobject1_1", []() -> MyObject1 * { return new MyObject1(4); });
    m.def("make_myobject1_2", []() -> ref<MyObject1> { return ref<MyObject1>(new MyObject1(5)); });
    m.def("print_object_1", [](const Object *obj) { py::print(obj->toString()); });
    m.def("print_object_2", [](ref<Object> obj) { py::print(obj->toString()); });
    m.def("print_object_3", [](const ref<Object> &obj) { py::print(obj->toString()); });
    m.def("print_object_4", [](const ref<Object> *obj) { py::print((*obj)->toString()); });
    m.def("print_myobject1_1", [](const MyObject1 *obj) { py::print(obj->toString()); });
    m.def("print_myobject1_2", [](ref<MyObject1> obj) { py::print(obj->toString()); });
    m.def("print_myobject1_3", [](const ref<MyObject1> &obj) { py::print(obj->toString()); });
    m.def("print_myobject1_4", [](const ref<MyObject1> *obj) { py::print((*obj)->toString()); });

    // Expose constructor stats for the ref type
    m.def("cstats_ref", &ConstructorStats::get<ref_tag>);

    py::class_<MyObject2, std::shared_ptr<MyObject2>>(m, "MyObject2").def(py::init<int>());
    m.def("make_myobject2_1", []() { return new MyObject2(6); });
    m.def("make_myobject2_2", []() { return std::make_shared<MyObject2>(7); });
    m.def("print_myobject2_1", [](const MyObject2 *obj) { py::print(obj->toString()); });
    // NOLINTNEXTLINE(performance-unnecessary-value-param)
    m.def("print_myobject2_2", [](std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); });
    m.def("print_myobject2_3",
          [](const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); });
    m.def("print_myobject2_4",
          [](const std::shared_ptr<MyObject2> *obj) { py::print((*obj)->toString()); });

    py::class_<MyObject3, std::shared_ptr<MyObject3>>(m, "MyObject3").def(py::init<int>());
    m.def("make_myobject3_1", []() { return new MyObject3(8); });
    m.def("make_myobject3_2", []() { return std::make_shared<MyObject3>(9); });
    m.def("print_myobject3_1", [](const MyObject3 *obj) { py::print(obj->toString()); });
    // NOLINTNEXTLINE(performance-unnecessary-value-param)
    m.def("print_myobject3_2", [](std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); });
    m.def("print_myobject3_3",
          [](const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); });
    m.def("print_myobject3_4",
          [](const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); });

    // test_smart_ptr_refcounting
    m.def("test_object1_refcounting", []() {
        auto o = ref<MyObject1>(new MyObject1(0));
        bool good = o->getRefCount() == 1;
        py::object o2 = py::cast(o, py::return_value_policy::reference);
        // always request (partial) ownership for objects with intrusive
        // reference counting even when using the 'reference' RVP
        good &= o->getRefCount() == 2;
        return good;
    });

    // test_unique_nodelete
    py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(m, "MyObject4")
        .def(py::init<int>())
        .def_readwrite("value", &MyObject4::value)
        .def_static("cleanup_all_instances", &MyObject4::cleanupAllInstances);

    // test_unique_deleter
    py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(m, "MyObject4a")
        .def(py::init<int>())
        .def_readwrite("value", &MyObject4a::value)
        .def_static("cleanup_all_instances", &MyObject4a::cleanupAllInstances);

    py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(m, "MyObject4b")
        .def(py::init<int>());

    // test_large_holder
    py::class_<MyObject5, huge_unique_ptr<MyObject5>>(m, "MyObject5")
        .def(py::init<int>())
        .def_readwrite("value", &MyObject5::value);

    // test_shared_ptr_and_references
    using A = SharedPtrRef::A;
    py::class_<A, std::shared_ptr<A>>(m, "A");
    py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(m, "SharedPtrRef")
        .def(py::init<>())
        .def_readonly("ref", &SharedPtrRef::value)
        .def_property_readonly(
            "copy", [](const SharedPtrRef &s) { return s.value; }, py::return_value_policy::copy)
        .def_readonly("holder_ref", &SharedPtrRef::shared)
        .def_property_readonly(
            "holder_copy",
            [](const SharedPtrRef &s) { return s.shared; },
            py::return_value_policy::copy)
        .def("set_ref", [](SharedPtrRef &, const A &) { return true; })
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def("set_holder", [](SharedPtrRef &, std::shared_ptr<A>) { return true; });

    // test_shared_ptr_from_this_and_references
    using B = SharedFromThisRef::B;
    py::class_<B, std::shared_ptr<B>>(m, "B");
    py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(m, "SharedFromThisRef")
        .def(py::init<>())
        .def_readonly("bad_wp", &SharedFromThisRef::value)
        .def_property_readonly("ref",
                               [](const SharedFromThisRef &s) -> const B & { return *s.shared; })
        .def_property_readonly(
            "copy",
            [](const SharedFromThisRef &s) { return s.value; },
            py::return_value_policy::copy)
        .def_readonly("holder_ref", &SharedFromThisRef::shared)
        .def_property_readonly(
            "holder_copy",
            [](const SharedFromThisRef &s) { return s.shared; },
            py::return_value_policy::copy)
        .def("set_ref", [](SharedFromThisRef &, const B &) { return true; })
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def("set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) { return true; });

    // Issue #865: shared_from_this doesn't work with virtual inheritance
    static std::shared_ptr<SharedFromThisVirt> sft(new SharedFromThisVirt());
    py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(m, "SharedFromThisVirt")
        .def_static("get", []() { return sft.get(); });

    // test_move_only_holder
    py::class_<C, custom_unique_ptr<C>>(m, "TypeWithMoveOnlyHolder")
        .def_static("make", []() { return custom_unique_ptr<C>(new C); })
        .def_static("make_as_object", []() { return py::cast(custom_unique_ptr<C>(new C)); });

    // test_holder_with_addressof_operator
    using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;
    py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(m, "TypeForHolderWithAddressOf")
        .def_static("make", []() { return HolderWithAddressOf(new TypeForHolderWithAddressOf); })
        .def("get", [](const HolderWithAddressOf &self) { return self.get(); })
        .def("print_object_1",
             [](const TypeForHolderWithAddressOf *obj) { py::print(obj->toString()); })
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def("print_object_2", [](HolderWithAddressOf obj) { py::print(obj.get()->toString()); })
        .def("print_object_3",
             [](const HolderWithAddressOf &obj) { py::print(obj.get()->toString()); })
        .def("print_object_4",
             [](const HolderWithAddressOf *obj) { py::print((*obj).get()->toString()); });

    // test_move_only_holder_with_addressof_operator
    using MoveOnlyHolderWithAddressOf
        = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;
    py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(
        m, "TypeForMoveOnlyHolderWithAddressOf")
        .def_static("make",
                    []() {
                        return MoveOnlyHolderWithAddressOf(
                            new TypeForMoveOnlyHolderWithAddressOf(0));
                    })
        .def_readwrite("value", &TypeForMoveOnlyHolderWithAddressOf::value)
        .def("print_object",
             [](const TypeForMoveOnlyHolderWithAddressOf *obj) { py::print(obj->toString()); });

    // test_smart_ptr_from_default
    py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(m, "HeldByDefaultHolder")
        .def(py::init<>())
        // NOLINTNEXTLINE(performance-unnecessary-value-param)
        .def_static("load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});

    // test_shared_ptr_gc
    // #187: issue involving std::shared_ptr<> return value policy & garbage collection
    py::class_<ElementBase, std::shared_ptr<ElementBase>>(m, "ElementBase");

    py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m, "ElementA")
        .def(py::init<int>())
        .def("value", &ElementA::value);

    py::class_<ElementList, std::shared_ptr<ElementList>>(m, "ElementList")
        .def(py::init<>())
        .def("add", &ElementList::add)
        .def("get", [](ElementList &el) {
            py::list list;
            for (auto &e : el.l) {
                list.append(py::cast(e));
            }
            return list;
        });
}
