/*
    tests/pybind11_tests.cpp -- pybind example plugin

    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"

#include <functional>
#include <list>

/*
For testing purposes, we define a static global variable here in a function that each individual
test .cpp calls with its initialization lambda.  It's convenient here because we can just not
compile some test files to disable/ignore some of the test code.

It is NOT recommended as a way to use pybind11 in practice, however: the initialization order will
be essentially random, which is okay for our test scripts (there are no dependencies between the
individual pybind11 test .cpp files), but most likely not what you want when using pybind11
productively.

Instead, see the "How can I reduce the build time?" question in the "Frequently asked questions"
section of the documentation for good practice on splitting binding code over multiple files.
*/
std::list<std::function<void(py::module_ &)>> &initializers() {
    static std::list<std::function<void(py::module_ &)>> inits;
    return inits;
}

test_initializer::test_initializer(Initializer init) { initializers().emplace_back(init); }

test_initializer::test_initializer(const char *submodule_name, Initializer init) {
    initializers().emplace_back([=](py::module_ &parent) {
        auto m = parent.def_submodule(submodule_name);
        init(m);
    });
}

void bind_ConstructorStats(py::module_ &m) {
    py::class_<ConstructorStats>(m, "ConstructorStats")
        .def("alive", &ConstructorStats::alive)
        .def("values", &ConstructorStats::values)
        .def_readwrite("default_constructions", &ConstructorStats::default_constructions)
        .def_readwrite("copy_assignments", &ConstructorStats::copy_assignments)
        .def_readwrite("move_assignments", &ConstructorStats::move_assignments)
        .def_readwrite("copy_constructions", &ConstructorStats::copy_constructions)
        .def_readwrite("move_constructions", &ConstructorStats::move_constructions)
        .def_static("get",
                    (ConstructorStats & (*)(py::object)) & ConstructorStats::get,
                    py::return_value_policy::reference_internal)

        // Not exactly ConstructorStats, but related: expose the internal pybind number of
        // registered instances to allow instance cleanup checks (invokes a GC first)
        .def_static("detail_reg_inst", []() {
            ConstructorStats::gc();
            return py::detail::num_registered_instances();
        });
}

const char *cpp_std() {
    return
#if defined(PYBIND11_CPP20)
        "C++20";
#elif defined(PYBIND11_CPP17)
        "C++17";
#elif defined(PYBIND11_CPP14)
        "C++14";
#else
        "C++11";
#endif
}

PYBIND11_MODULE(pybind11_tests, m, py::mod_gil_not_used()) {
    m.doc() = "pybind11 test module";

    // Intentionally kept minimal to not create a maintenance chore
    // ("just enough" to be conclusive).
#if defined(__VERSION__)
    m.attr("compiler_info") = __VERSION__;
#elif defined(_MSC_FULL_VER)
    m.attr("compiler_info") = "MSVC " PYBIND11_TOSTRING(_MSC_FULL_VER);
#else
    m.attr("compiler_info") = py::none();
#endif
    m.attr("cpp_std") = cpp_std();
    m.attr("PYBIND11_INTERNALS_ID") = PYBIND11_INTERNALS_ID;
    // Free threaded Python uses UINT32_MAX for immortal objects.
    m.attr("PYBIND11_SIMPLE_GIL_MANAGEMENT") =
#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
        true;
#else
        false;
#endif
    m.attr("PYBIND11_TEST_SMART_HOLDER") =
#if defined(PYBIND11_RUN_TESTING_WITH_SMART_HOLDER_AS_DEFAULT_BUT_NEVER_USE_IN_PRODUCTION_PLEASE)
        true;
#else
        false;
#endif

    bind_ConstructorStats(m);

#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
    m.attr("detailed_error_messages_enabled") = true;
#else
    m.attr("detailed_error_messages_enabled") = false;
#endif

#if defined(__cpp_noexcept_function_type)
    m.attr("defined___cpp_noexcept_function_type") = true;
#else
    m.attr("defined___cpp_noexcept_function_type") = false;
#endif

    py::class_<UserType>(m, "UserType", "A `py::class_` type for testing")
        .def(py::init<>())
        .def(py::init<int>())
        .def("get_value", &UserType::value, "Get value using a method")
        .def("set_value", &UserType::set, "Set value using a method")
        .def_property("value", &UserType::value, &UserType::set, "Get/set value using a property")
        .def("__repr__", [](const UserType &u) { return "UserType({})"_s.format(u.value()); });

    py::class_<IncType, UserType>(m, "IncType")
        .def(py::init<>())
        .def(py::init<int>())
        .def("__repr__", [](const IncType &u) { return "IncType({})"_s.format(u.value()); });

    for (const auto &initializer : initializers()) {
        initializer(m);
    }

    py::class_<TestContext>(m, "TestContext")
        .def(py::init<>(&TestContext::createNewContextForInit))
        .def("__enter__", &TestContext::contextEnter)
        .def("__exit__", &TestContext::contextExit);
}
