/*
    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 "constructor_stats.h"
#include "pybind11_tests.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;
    });

    m.def("def_submodule", [](py::module_ m, const char *name) { return m.def_submodule(name); });
}
