#pragma once
/*
    tests/constructor_stats.h -- framework for printing and tracking object
    instance lifetimes in example/test code.

    Copyright (c) 2016 Jason Rhinelander <jason@imaginary.ca>

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

This header provides a few useful tools for writing examples or tests that want to check and/or
display object instance lifetimes.  It requires that you include this header and add the following
function calls to constructors:

    class MyClass {
        MyClass() { ...; print_default_created(this); }
        ~MyClass() { ...; print_destroyed(this); }
        MyClass(const MyClass &c) { ...; print_copy_created(this); }
        MyClass(MyClass &&c) { ...; print_move_created(this); }
        MyClass(int a, int b) { ...; print_created(this, a, b); }
        MyClass &operator=(const MyClass &c) { ...; print_copy_assigned(this); }
        MyClass &operator=(MyClass &&c) { ...; print_move_assigned(this); }

        ...
    }

You can find various examples of these in several of the existing testing .cpp files.  (Of course
you don't need to add any of the above constructors/operators that you don't actually have, except
for the destructor).

Each of these will print an appropriate message such as:

    ### MyClass @ 0x2801910 created via default constructor
    ### MyClass @ 0x27fa780 created 100 200
    ### MyClass @ 0x2801910 destroyed
    ### MyClass @ 0x27fa780 destroyed

You can also include extra arguments (such as the 100, 200 in the output above, coming from the
value constructor) for all of the above methods which will be included in the output.

For testing, each of these also keeps track the created instances and allows you to check how many
of the various constructors have been invoked from the Python side via code such as:

    from pybind11_tests import ConstructorStats
    cstats = ConstructorStats.get(MyClass)
    print(cstats.alive())
    print(cstats.default_constructions)

Note that `.alive()` should usually be the first thing you call as it invokes Python's garbage
collector to actually destroy objects that aren't yet referenced.

For everything except copy and move constructors and destructors, any extra values given to the
print_...() function is stored in a class-specific values list which you can retrieve and inspect
from the ConstructorStats instance `.values()` method.

In some cases, when you need to track instances of a C++ class not registered with pybind11, you
need to add a function returning the ConstructorStats for the C++ class; this can be done with:

    m.def("get_special_cstats", &ConstructorStats::get<SpecialClass>, py::return_value_policy::reference)

Finally, you can suppress the output messages, but keep the constructor tracking (for
inspection/testing in python) by using the functions with `print_` replaced with `track_` (e.g.
`track_copy_created(this)`).

*/

#include "pybind11_tests.h"
#include <unordered_map>
#include <list>
#include <typeindex>
#include <sstream>

class ConstructorStats {
protected:
    std::unordered_map<void*, int> _instances; // Need a map rather than set because members can shared address with parents
    std::list<std::string> _values; // Used to track values (e.g. of value constructors)
public:
    int default_constructions = 0;
    int copy_constructions = 0;
    int move_constructions = 0;
    int copy_assignments = 0;
    int move_assignments = 0;

    void copy_created(void *inst) {
        created(inst);
        copy_constructions++;
    }

    void move_created(void *inst) {
        created(inst);
        move_constructions++;
    }

    void default_created(void *inst) {
        created(inst);
        default_constructions++;
    }

    void created(void *inst) {
        ++_instances[inst];
    }

    void destroyed(void *inst) {
        if (--_instances[inst] < 0)
            throw std::runtime_error("cstats.destroyed() called with unknown "
                                     "instance; potential double-destruction "
                                     "or a missing cstats.created()");
    }

    static void gc() {
        // Force garbage collection to ensure any pending destructors are invoked:
#if defined(PYPY_VERSION)
        PyObject *globals = PyEval_GetGlobals();
        PyObject *result = PyRun_String(
            "import gc\n"
            "for i in range(2):"
            "    gc.collect()\n",
            Py_file_input, globals, globals);
        if (result == nullptr)
            throw py::error_already_set();
        Py_DECREF(result);
#else
        py::module_::import("gc").attr("collect")();
#endif
    }

    int alive() {
        gc();
        int total = 0;
        for (const auto &p : _instances)
            if (p.second > 0)
                total += p.second;
        return total;
    }

    void value() {} // Recursion terminator
    // Takes one or more values, converts them to strings, then stores them.
    template <typename T, typename... Tmore> void value(const T &v, Tmore &&...args) {
        std::ostringstream oss;
        oss << v;
        _values.push_back(oss.str());
        value(std::forward<Tmore>(args)...);
    }

    // Move out stored values
    py::list values() {
        py::list l;
        for (const auto &v : _values) l.append(py::cast(v));
        _values.clear();
        return l;
    }

    // Gets constructor stats from a C++ type index
    static ConstructorStats& get(std::type_index type) {
        static std::unordered_map<std::type_index, ConstructorStats> all_cstats;
        return all_cstats[type];
    }

    // Gets constructor stats from a C++ type
    template <typename T> static ConstructorStats& get() {
#if defined(PYPY_VERSION)
        gc();
#endif
        return get(typeid(T));
    }

    // Gets constructor stats from a Python class
    static ConstructorStats& get(py::object class_) {
        auto &internals = py::detail::get_internals();
        const std::type_index *t1 = nullptr, *t2 = nullptr;
        try {
            auto *type_info = internals.registered_types_py.at((PyTypeObject *) class_.ptr()).at(0);
            for (auto &p : internals.registered_types_cpp) {
                if (p.second == type_info) {
                    if (t1) {
                        t2 = &p.first;
                        break;
                    }
                    t1 = &p.first;
                }
            }
        }
        catch (const std::out_of_range&) {}
        if (!t1) throw std::runtime_error("Unknown class passed to ConstructorStats::get()");
        auto &cs1 = get(*t1);
        // If we have both a t1 and t2 match, one is probably the trampoline class; return whichever
        // has more constructions (typically one or the other will be 0)
        if (t2) {
            auto &cs2 = get(*t2);
            int cs1_total = cs1.default_constructions + cs1.copy_constructions + cs1.move_constructions + (int) cs1._values.size();
            int cs2_total = cs2.default_constructions + cs2.copy_constructions + cs2.move_constructions + (int) cs2._values.size();
            if (cs2_total > cs1_total) return cs2;
        }
        return cs1;
    }
};

// To track construction/destruction, you need to call these methods from the various
// constructors/operators.  The ones that take extra values record the given values in the
// constructor stats values for later inspection.
template <class T> void track_copy_created(T *inst) { ConstructorStats::get<T>().copy_created(inst); }
template <class T> void track_move_created(T *inst) { ConstructorStats::get<T>().move_created(inst); }
template <class T, typename... Values> void track_copy_assigned(T *, Values &&...values) {
    auto &cst = ConstructorStats::get<T>();
    cst.copy_assignments++;
    cst.value(std::forward<Values>(values)...);
}
template <class T, typename... Values> void track_move_assigned(T *, Values &&...values) {
    auto &cst = ConstructorStats::get<T>();
    cst.move_assignments++;
    cst.value(std::forward<Values>(values)...);
}
template <class T, typename... Values> void track_default_created(T *inst, Values &&...values) {
    auto &cst = ConstructorStats::get<T>();
    cst.default_created(inst);
    cst.value(std::forward<Values>(values)...);
}
template <class T, typename... Values> void track_created(T *inst, Values &&...values) {
    auto &cst = ConstructorStats::get<T>();
    cst.created(inst);
    cst.value(std::forward<Values>(values)...);
}
template <class T, typename... Values> void track_destroyed(T *inst) {
    ConstructorStats::get<T>().destroyed(inst);
}
template <class T, typename... Values> void track_values(T *, Values &&...values) {
    ConstructorStats::get<T>().value(std::forward<Values>(values)...);
}

/// Don't cast pointers to Python, print them as strings
inline const char *format_ptrs(const char *p) { return p; }
template <typename T>
py::str format_ptrs(T *p) { return "{:#x}"_s.format(reinterpret_cast<std::uintptr_t>(p)); }
template <typename T>
auto format_ptrs(T &&x) -> decltype(std::forward<T>(x)) { return std::forward<T>(x); }

template <class T, typename... Output>
void print_constr_details(T *inst, const std::string &action, Output &&...output) {
    py::print("###", py::type_id<T>(), "@", format_ptrs(inst), action,
              format_ptrs(std::forward<Output>(output))...);
}

// Verbose versions of the above:
template <class T, typename... Values> void print_copy_created(T *inst, Values &&...values) { // NB: this prints, but doesn't store, given values
    print_constr_details(inst, "created via copy constructor", values...);
    track_copy_created(inst);
}
template <class T, typename... Values> void print_move_created(T *inst, Values &&...values) { // NB: this prints, but doesn't store, given values
    print_constr_details(inst, "created via move constructor", values...);
    track_move_created(inst);
}
template <class T, typename... Values> void print_copy_assigned(T *inst, Values &&...values) {
    print_constr_details(inst, "assigned via copy assignment", values...);
    track_copy_assigned(inst, values...);
}
template <class T, typename... Values> void print_move_assigned(T *inst, Values &&...values) {
    print_constr_details(inst, "assigned via move assignment", values...);
    track_move_assigned(inst, values...);
}
template <class T, typename... Values> void print_default_created(T *inst, Values &&...values) {
    print_constr_details(inst, "created via default constructor", values...);
    track_default_created(inst, values...);
}
template <class T, typename... Values> void print_created(T *inst, Values &&...values) {
    print_constr_details(inst, "created", values...);
    track_created(inst, values...);
}
template <class T, typename... Values> void print_destroyed(T *inst, Values &&...values) { // Prints but doesn't store given values
    print_constr_details(inst, "destroyed", values...);
    track_destroyed(inst);
}
template <class T, typename... Values> void print_values(T *inst, Values &&...values) {
    print_constr_details(inst, ":", values...);
    track_values(inst, values...);
}
