/*
    tests/test_virtual_functions.cpp -- overriding virtual functions from Python

    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/functional.h>

#include "constructor_stats.h"
#include "pybind11_tests.h"

#include <thread>

/* This is an example class that we'll want to be able to extend from Python */
class ExampleVirt {
public:
    explicit ExampleVirt(int state) : state(state) { print_created(this, state); }
    ExampleVirt(const ExampleVirt &e) : state(e.state) { print_copy_created(this); }
    ExampleVirt(ExampleVirt &&e) noexcept : state(e.state) {
        print_move_created(this);
        e.state = 0;
    }
    virtual ~ExampleVirt() { print_destroyed(this); }

    virtual int run(int value) {
        py::print("Original implementation of "
                  "ExampleVirt::run(state={}, value={}, str1={}, str2={})"_s.format(
                      state, value, get_string1(), *get_string2()));
        return state + value;
    }

    virtual bool run_bool() = 0;
    virtual void pure_virtual() = 0;

    // Returning a reference/pointer to a type converted from python (numbers, strings, etc.) is a
    // bit trickier, because the actual int& or std::string& or whatever only exists temporarily,
    // so we have to handle it specially in the trampoline class (see below).
    virtual const std::string &get_string1() { return str1; }
    virtual const std::string *get_string2() { return &str2; }

private:
    int state;
    const std::string str1{"default1"}, str2{"default2"};
};

/* This is a wrapper class that must be generated */
class PyExampleVirt : public ExampleVirt {
public:
    using ExampleVirt::ExampleVirt; /* Inherit constructors */

    int run(int value) override {
        /* Generate wrapping code that enables native function overloading */
        PYBIND11_OVERRIDE(int,         /* Return type */
                          ExampleVirt, /* Parent class */
                          run,         /* Name of function */
                          value        /* Argument(s) */
        );
    }

    bool run_bool() override {
        PYBIND11_OVERRIDE_PURE(bool,        /* Return type */
                               ExampleVirt, /* Parent class */
                               run_bool,    /* Name of function */
                                            /* This function has no arguments. The trailing comma
                                               in the previous line is needed for some compilers */
        );
    }

    void pure_virtual() override {
        PYBIND11_OVERRIDE_PURE(void,         /* Return type */
                               ExampleVirt,  /* Parent class */
                               pure_virtual, /* Name of function */
                                             /* This function has no arguments. The trailing comma
                                                in the previous line is needed for some compilers */
        );
    }

    // We can return reference types for compatibility with C++ virtual interfaces that do so, but
    // note they have some significant limitations (see the documentation).
    const std::string &get_string1() override {
        PYBIND11_OVERRIDE(const std::string &, /* Return type */
                          ExampleVirt,         /* Parent class */
                          get_string1,         /* Name of function */
                                               /* (no arguments) */
        );
    }

    const std::string *get_string2() override {
        PYBIND11_OVERRIDE(const std::string *, /* Return type */
                          ExampleVirt,         /* Parent class */
                          get_string2,         /* Name of function */
                                               /* (no arguments) */
        );
    }
};

class NonCopyable {
public:
    NonCopyable(int a, int b) : value{new int(a * b)} { print_created(this, a, b); }
    NonCopyable(NonCopyable &&o) noexcept : value{std::move(o.value)} { print_move_created(this); }
    NonCopyable(const NonCopyable &) = delete;
    NonCopyable() = delete;
    void operator=(const NonCopyable &) = delete;
    void operator=(NonCopyable &&) = delete;
    std::string get_value() const {
        if (value) {
            return std::to_string(*value);
        }
        return "(null)";
    }
    ~NonCopyable() { print_destroyed(this); }

private:
    std::unique_ptr<int> value;
};

// This is like the above, but is both copy and movable.  In effect this means it should get moved
// when it is not referenced elsewhere, but copied if it is still referenced.
class Movable {
public:
    Movable(int a, int b) : value{a + b} { print_created(this, a, b); }
    Movable(const Movable &m) : value{m.value} { print_copy_created(this); }
    Movable(Movable &&m) noexcept : value{m.value} { print_move_created(this); }
    std::string get_value() const { return std::to_string(value); }
    ~Movable() { print_destroyed(this); }

private:
    int value;
};

class NCVirt {
public:
    virtual ~NCVirt() = default;
    NCVirt() = default;
    NCVirt(const NCVirt &) = delete;
    virtual NonCopyable get_noncopyable(int a, int b) { return NonCopyable(a, b); }
    virtual Movable get_movable(int a, int b) = 0;

    std::string print_nc(int a, int b) { return get_noncopyable(a, b).get_value(); }
    std::string print_movable(int a, int b) { return get_movable(a, b).get_value(); }
};
class NCVirtTrampoline : public NCVirt {
#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)
    NonCopyable get_noncopyable(int a, int b) override {
        PYBIND11_OVERRIDE(NonCopyable, NCVirt, get_noncopyable, a, b);
    }
#endif
    Movable get_movable(int a, int b) override {
        PYBIND11_OVERRIDE_PURE(Movable, NCVirt, get_movable, a, b);
    }
};

struct Base {
    virtual std::string dispatch() const = 0;
    virtual ~Base() = default;
    Base() = default;
    Base(const Base &) = delete;
};

struct DispatchIssue : Base {
    std::string dispatch() const override {
        PYBIND11_OVERRIDE_PURE(std::string, Base, dispatch, /* no arguments */);
    }
};

// An abstract adder class that uses visitor pattern to add two data
// objects and send the result to the visitor functor
struct AdderBase {
    struct Data {};
    using DataVisitor = std::function<void(const Data &)>;

    virtual void
    operator()(const Data &first, const Data &second, const DataVisitor &visitor) const = 0;
    virtual ~AdderBase() = default;
    AdderBase() = default;
    AdderBase(const AdderBase &) = delete;
};

struct Adder : AdderBase {
    void
    operator()(const Data &first, const Data &second, const DataVisitor &visitor) const override {
        PYBIND11_OVERRIDE_PURE_NAME(
            void, AdderBase, "__call__", operator(), first, second, visitor);
    }
};

static void test_gil() {
    {
        py::gil_scoped_acquire lock;
        py::print("1st lock acquired");
    }

    {
        py::gil_scoped_acquire lock;
        py::print("2nd lock acquired");
    }
}

static void test_gil_from_thread() {
    py::gil_scoped_release release;

    std::thread t(test_gil);
    t.join();
}

class test_override_cache_helper {

public:
    virtual int func() { return 0; }

    test_override_cache_helper() = default;
    virtual ~test_override_cache_helper() = default;
    // Non-copyable
    test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;
    test_override_cache_helper(test_override_cache_helper const &Copy) = delete;
};

class test_override_cache_helper_trampoline : public test_override_cache_helper {
    int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }
};

inline int test_override_cache(std::shared_ptr<test_override_cache_helper> const &instance) {
    return instance->func();
}

// Forward declaration (so that we can put the main tests here; the inherited virtual approaches
// are rather long).
void initialize_inherited_virtuals(py::module_ &m);

TEST_SUBMODULE(virtual_functions, m) {
    // test_override
    py::class_<ExampleVirt, PyExampleVirt>(m, "ExampleVirt")
        .def(py::init<int>())
        /* Reference original class in function definitions */
        .def("run", &ExampleVirt::run)
        .def("run_bool", &ExampleVirt::run_bool)
        .def("pure_virtual", &ExampleVirt::pure_virtual);

    py::class_<NonCopyable>(m, "NonCopyable").def(py::init<int, int>());

    py::class_<Movable>(m, "Movable").def(py::init<int, int>());

    // test_move_support
#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)
    py::class_<NCVirt, NCVirtTrampoline>(m, "NCVirt")
        .def(py::init<>())
        .def("get_noncopyable", &NCVirt::get_noncopyable)
        .def("get_movable", &NCVirt::get_movable)
        .def("print_nc", &NCVirt::print_nc)
        .def("print_movable", &NCVirt::print_movable);
#endif

    m.def("runExampleVirt", [](ExampleVirt *ex, int value) { return ex->run(value); });
    m.def("runExampleVirtBool", [](ExampleVirt *ex) { return ex->run_bool(); });
    m.def("runExampleVirtVirtual", [](ExampleVirt *ex) { ex->pure_virtual(); });

    m.def("cstats_debug", &ConstructorStats::get<ExampleVirt>);
    initialize_inherited_virtuals(m);

    // test_alias_delay_initialization1
    // don't invoke Python dispatch classes by default when instantiating C++ classes
    // that were not extended on the Python side
    struct A {
        A() = default;
        A(const A &) = delete;
        virtual ~A() = default;
        virtual void f() { py::print("A.f()"); }
    };

    struct PyA : A {
        PyA() { py::print("PyA.PyA()"); }
        PyA(const PyA &) = delete;
        ~PyA() override { py::print("PyA.~PyA()"); }

        void f() override {
            py::print("PyA.f()");
            // This convolution just gives a `void`, but tests that PYBIND11_TYPE() works to
            // protect a type containing a ,
            PYBIND11_OVERRIDE(PYBIND11_TYPE(typename std::enable_if<true, void>::type), A, f);
        }
    };

    py::class_<A, PyA>(m, "A").def(py::init<>()).def("f", &A::f);

    m.def("call_f", [](A *a) { a->f(); });

    // test_alias_delay_initialization2
    // ... unless we explicitly request it, as in this example:
    struct A2 {
        A2() = default;
        A2(const A2 &) = delete;
        virtual ~A2() = default;
        virtual void f() { py::print("A2.f()"); }
    };

    struct PyA2 : A2 {
        PyA2() { py::print("PyA2.PyA2()"); }
        PyA2(const PyA2 &) = delete;
        ~PyA2() override { py::print("PyA2.~PyA2()"); }
        void f() override {
            py::print("PyA2.f()");
            PYBIND11_OVERRIDE(void, A2, f);
        }
    };

    py::class_<A2, PyA2>(m, "A2")
        .def(py::init_alias<>())
        .def(py::init([](int) { return new PyA2(); }))
        .def("f", &A2::f);

    m.def("call_f", [](A2 *a2) { a2->f(); });

    // test_dispatch_issue
    // #159: virtual function dispatch has problems with similar-named functions
    py::class_<Base, DispatchIssue>(m, "DispatchIssue")
        .def(py::init<>())
        .def("dispatch", &Base::dispatch);

    m.def("dispatch_issue_go", [](const Base *b) { return b->dispatch(); });

    // test_recursive_dispatch_issue
    // #3357: Recursive dispatch fails to find python function override
    pybind11::class_<AdderBase, Adder>(m, "Adder")
        .def(pybind11::init<>())
        .def("__call__", &AdderBase::operator());

    pybind11::class_<AdderBase::Data>(m, "Data").def(pybind11::init<>());

    m.def("add2",
          [](const AdderBase::Data &first,
             const AdderBase::Data &second,
             const AdderBase &adder,
             const AdderBase::DataVisitor &visitor) { adder(first, second, visitor); });

    m.def("add3",
          [](const AdderBase::Data &first,
             const AdderBase::Data &second,
             const AdderBase::Data &third,
             const AdderBase &adder,
             const AdderBase::DataVisitor &visitor) {
              adder(first, second, [&](const AdderBase::Data &first_plus_second) {
                  // NOLINTNEXTLINE(readability-suspicious-call-argument)
                  adder(first_plus_second, third, visitor);
              });
          });

    // test_override_ref
    // #392/397: overriding reference-returning functions
    class OverrideTest {
    public:
        struct A {
            std::string value = "hi";
        };
        std::string v;
        A a;
        explicit OverrideTest(const std::string &v) : v{v} {}
        OverrideTest() = default;
        OverrideTest(const OverrideTest &) = delete;
        virtual std::string str_value() { return v; }
        virtual std::string &str_ref() { return v; }
        virtual A A_value() { return a; }
        virtual A &A_ref() { return a; }
        virtual ~OverrideTest() = default;
    };

    class PyOverrideTest : public OverrideTest {
    public:
        using OverrideTest::OverrideTest;
        std::string str_value() override {
            PYBIND11_OVERRIDE(std::string, OverrideTest, str_value);
        }
        // Not allowed (enabling the below should hit a static_assert failure): we can't get a
        // reference to a python numeric value, since we only copy values in the numeric type
        // caster:
#ifdef PYBIND11_NEVER_DEFINED_EVER
        std::string &str_ref() override {
            PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref);
        }
#endif
        // But we can work around it like this:
    private:
        std::string _tmp;
        std::string str_ref_helper() { PYBIND11_OVERRIDE(std::string, OverrideTest, str_ref); }

    public:
        std::string &str_ref() override { return _tmp = str_ref_helper(); }

        A A_value() override { PYBIND11_OVERRIDE(A, OverrideTest, A_value); }
        A &A_ref() override { PYBIND11_OVERRIDE(A &, OverrideTest, A_ref); }
    };

    py::class_<OverrideTest::A>(m, "OverrideTest_A")
        .def_readwrite("value", &OverrideTest::A::value);
    py::class_<OverrideTest, PyOverrideTest>(m, "OverrideTest")
        .def(py::init<const std::string &>())
        .def("str_value", &OverrideTest::str_value)
#ifdef PYBIND11_NEVER_DEFINED_EVER
        .def("str_ref", &OverrideTest::str_ref)
#endif
        .def("A_value", &OverrideTest::A_value)
        .def("A_ref", &OverrideTest::A_ref);

    py::class_<test_override_cache_helper,
               test_override_cache_helper_trampoline,
               std::shared_ptr<test_override_cache_helper>>(m, "test_override_cache_helper")
        .def(py::init_alias<>())
        .def("func", &test_override_cache_helper::func);

    m.def("test_override_cache", test_override_cache);
}

// Inheriting virtual methods.  We do two versions here: the repeat-everything version and the
// templated trampoline versions mentioned in docs/advanced.rst.
//
// These base classes are exactly the same, but we technically need distinct
// classes for this example code because we need to be able to bind them
// properly (pybind11, sensibly, doesn't allow us to bind the same C++ class to
// multiple python classes).
class A_Repeat {
#define A_METHODS                                                                                 \
public:                                                                                           \
    virtual int unlucky_number() = 0;                                                             \
    virtual std::string say_something(unsigned times) {                                           \
        std::string s = "";                                                                       \
        for (unsigned i = 0; i < times; ++i)                                                      \
            s += "hi";                                                                            \
        return s;                                                                                 \
    }                                                                                             \
    std::string say_everything() {                                                                \
        return say_something(1) + " " + std::to_string(unlucky_number());                         \
    }
    A_METHODS
    A_Repeat() = default;
    A_Repeat(const A_Repeat &) = delete;
    virtual ~A_Repeat() = default;
};
class B_Repeat : public A_Repeat {
#define B_METHODS                                                                                 \
public:                                                                                           \
    int unlucky_number() override { return 13; }                                                  \
    std::string say_something(unsigned times) override {                                          \
        return "B says hi " + std::to_string(times) + " times";                                   \
    }                                                                                             \
    virtual double lucky_number() { return 7.0; }
    B_METHODS
};
class C_Repeat : public B_Repeat {
#define C_METHODS                                                                                 \
public:                                                                                           \
    int unlucky_number() override { return 4444; }                                                \
    double lucky_number() override { return 888; }
    C_METHODS
};
class D_Repeat : public C_Repeat {
#define D_METHODS // Nothing overridden.
    D_METHODS
};

// Base classes for templated inheritance trampolines.  Identical to the repeat-everything version:
class A_Tpl {
    A_METHODS;
    A_Tpl() = default;
    A_Tpl(const A_Tpl &) = delete;
    virtual ~A_Tpl() = default;
};
class B_Tpl : public A_Tpl {
    B_METHODS
};
class C_Tpl : public B_Tpl {
    C_METHODS
};
class D_Tpl : public C_Tpl {
    D_METHODS
};

// Inheritance approach 1: each trampoline gets every virtual method (11 in total)
class PyA_Repeat : public A_Repeat {
public:
    using A_Repeat::A_Repeat;
    int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, A_Repeat, unlucky_number, ); }
    std::string say_something(unsigned times) override {
        PYBIND11_OVERRIDE(std::string, A_Repeat, say_something, times);
    }
};
class PyB_Repeat : public B_Repeat {
public:
    using B_Repeat::B_Repeat;
    int unlucky_number() override { PYBIND11_OVERRIDE(int, B_Repeat, unlucky_number, ); }
    std::string say_something(unsigned times) override {
        PYBIND11_OVERRIDE(std::string, B_Repeat, say_something, times);
    }
    double lucky_number() override { PYBIND11_OVERRIDE(double, B_Repeat, lucky_number, ); }
};
class PyC_Repeat : public C_Repeat {
public:
    using C_Repeat::C_Repeat;
    int unlucky_number() override { PYBIND11_OVERRIDE(int, C_Repeat, unlucky_number, ); }
    std::string say_something(unsigned times) override {
        PYBIND11_OVERRIDE(std::string, C_Repeat, say_something, times);
    }
    double lucky_number() override { PYBIND11_OVERRIDE(double, C_Repeat, lucky_number, ); }
};
class PyD_Repeat : public D_Repeat {
public:
    using D_Repeat::D_Repeat;
    int unlucky_number() override { PYBIND11_OVERRIDE(int, D_Repeat, unlucky_number, ); }
    std::string say_something(unsigned times) override {
        PYBIND11_OVERRIDE(std::string, D_Repeat, say_something, times);
    }
    double lucky_number() override { PYBIND11_OVERRIDE(double, D_Repeat, lucky_number, ); }
};

// Inheritance approach 2: templated trampoline classes.
//
// Advantages:
// - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one
//   for any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes
//   and 11 methods (repeat).
// - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and
//   can properly inherit constructors.
//
// Disadvantage:
// - the compiler must still generate and compile 14 different methods (more, even, than the 11
//   required for the repeat approach) instead of the 6 required for MI.  (If there was no pure
//   method (or no pure method override), the number would drop down to the same 11 as the repeat
//   approach).
template <class Base = A_Tpl>
class PyA_Tpl : public Base {
public:
    using Base::Base; // Inherit constructors
    int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, Base, unlucky_number, ); }
    std::string say_something(unsigned times) override {
        PYBIND11_OVERRIDE(std::string, Base, say_something, times);
    }
};
template <class Base = B_Tpl>
class PyB_Tpl : public PyA_Tpl<Base> {
public:
    using PyA_Tpl<Base>::PyA_Tpl; // Inherit constructors (via PyA_Tpl's inherited constructors)
    // NOLINTNEXTLINE(bugprone-parent-virtual-call)
    int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); }
    double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); }
};
// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these
// (we can use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead):
/*
template <class Base = C_Tpl> class PyC_Tpl : public PyB_Tpl<Base> {
public:
    using PyB_Tpl<Base>::PyB_Tpl;
};
template <class Base = D_Tpl> class PyD_Tpl : public PyC_Tpl<Base> {
public:
    using PyC_Tpl<Base>::PyC_Tpl;
};
*/

void initialize_inherited_virtuals(py::module_ &m) {
    // test_inherited_virtuals

    // Method 1: repeat
    py::class_<A_Repeat, PyA_Repeat>(m, "A_Repeat")
        .def(py::init<>())
        .def("unlucky_number", &A_Repeat::unlucky_number)
        .def("say_something", &A_Repeat::say_something)
        .def("say_everything", &A_Repeat::say_everything);
    py::class_<B_Repeat, A_Repeat, PyB_Repeat>(m, "B_Repeat")
        .def(py::init<>())
        .def("lucky_number", &B_Repeat::lucky_number);
    py::class_<C_Repeat, B_Repeat, PyC_Repeat>(m, "C_Repeat").def(py::init<>());
    py::class_<D_Repeat, C_Repeat, PyD_Repeat>(m, "D_Repeat").def(py::init<>());

    // test_
    // Method 2: Templated trampolines
    py::class_<A_Tpl, PyA_Tpl<>>(m, "A_Tpl")
        .def(py::init<>())
        .def("unlucky_number", &A_Tpl::unlucky_number)
        .def("say_something", &A_Tpl::say_something)
        .def("say_everything", &A_Tpl::say_everything);
    py::class_<B_Tpl, A_Tpl, PyB_Tpl<>>(m, "B_Tpl")
        .def(py::init<>())
        .def("lucky_number", &B_Tpl::lucky_number);
    py::class_<C_Tpl, B_Tpl, PyB_Tpl<C_Tpl>>(m, "C_Tpl").def(py::init<>());
    py::class_<D_Tpl, C_Tpl, PyB_Tpl<D_Tpl>>(m, "D_Tpl").def(py::init<>());

    // Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)
    m.def("test_gil", &test_gil);
    m.def("test_gil_from_thread", &test_gil_from_thread);
};
