/*
    tests/test_modules.cpp -- nested modules, importing modules, and
                            internal references

    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 "pybind11_tests.h"
#include "constructor_stats.h"

TEST_SUBMODULE(modules, m) {
    // test_nested_modules
    // This is intentionally "py::module" to verify it still can be used in place of "py::module_"
    py::module m_sub = m.def_submodule("subsubmodule");
    m_sub.def("submodule_func", []() { return "submodule_func()"; });

    // test_reference_internal
    class A {
    public:
        explicit A(int v) : v(v) { print_created(this, v); }
        ~A() { print_destroyed(this); }
        A(const A&) { print_copy_created(this); }
        A& operator=(const A &copy) { print_copy_assigned(this); v = copy.v; return *this; }
        std::string toString() const { return "A[" + std::to_string(v) + "]"; }

    private:
        int v;
    };
    py::class_<A>(m_sub, "A")
        .def(py::init<int>())
        .def("__repr__", &A::toString);

    class B {
    public:
        B() { print_default_created(this); }
        ~B() { print_destroyed(this); }
        B(const B&) { print_copy_created(this); }
        B& operator=(const B &copy) { print_copy_assigned(this); a1 = copy.a1; a2 = copy.a2; return *this; }
        A &get_a1() { return a1; }
        A &get_a2() { return a2; }

        A a1{1};
        A a2{2};
    };
    py::class_<B>(m_sub, "B")
        .def(py::init<>())
        .def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal)
        .def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal)
        .def_readwrite("a1", &B::a1)  // def_readonly uses an internal reference return policy by default
        .def_readwrite("a2", &B::a2);

    // This is intentionally "py::module" to verify it still can be used in place of "py::module_"
    m.attr("OD") = py::module::import("collections").attr("OrderedDict");

    // test_duplicate_registration
    // Registering two things with the same name
    m.def("duplicate_registration", []() {
        class Dupe1 { };
        class Dupe2 { };
        class Dupe3 { };
        class DupeException { };

        // Go ahead and leak, until we have a non-leaking py::module_ constructor
        auto dm = py::module_::create_extension_module("dummy", nullptr, new py::module_::module_def);
        auto failures = py::list();

        py::class_<Dupe1>(dm, "Dupe1");
        py::class_<Dupe2>(dm, "Dupe2");
        dm.def("dupe1_factory", []() { return Dupe1(); });
        py::exception<DupeException>(dm, "DupeException");

        try {
            py::class_<Dupe1>(dm, "Dupe1");
            failures.append("Dupe1 class");
        } catch (std::runtime_error &) {}
        try {
            dm.def("Dupe1", []() { return Dupe1(); });
            failures.append("Dupe1 function");
        } catch (std::runtime_error &) {}
        try {
            py::class_<Dupe3>(dm, "dupe1_factory");
            failures.append("dupe1_factory");
        } catch (std::runtime_error &) {}
        try {
            py::exception<Dupe3>(dm, "Dupe2");
            failures.append("Dupe2");
        } catch (std::runtime_error &) {}
        try {
            dm.def("DupeException", []() { return 30; });
            failures.append("DupeException1");
        } catch (std::runtime_error &) {}
        try {
            py::class_<DupeException>(dm, "DupeException");
            failures.append("DupeException2");
        } catch (std::runtime_error &) {}

        return failures;
    });
}
