/*
    tests/test_tagbased_polymorphic.cpp -- test of polymorphic_type_hook

    Copyright (c) 2018 Hudson River Trading LLC <opensource@hudson-trading.com>

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

#include "pybind11_tests.h"

struct Animal {
    // Make this type also a "standard" polymorphic type, to confirm that
    // specializing polymorphic_type_hook using enable_if_t still works
    // (https://github.com/pybind/pybind11/pull/2016/).
    virtual ~Animal() = default;

    // Enum for tag-based polymorphism.
    enum class Kind {
        Unknown = 0,
        Dog = 100,
        Labrador,
        Chihuahua,
        LastDog = 199,
        Cat = 200,
        Panther,
        LastCat = 299
    };
    static const std::type_info *type_of_kind(Kind kind);
    static std::string name_of_kind(Kind kind);

    const Kind kind;
    const std::string name;

protected:
    Animal(const std::string &_name, Kind _kind) : kind(_kind), name(_name) {}
};

struct Dog : Animal {
    explicit Dog(const std::string &_name, Kind _kind = Kind::Dog) : Animal(_name, _kind) {}
    std::string bark() const { return name_of_kind(kind) + " " + name + " goes " + sound; }
    std::string sound = "WOOF!";
};

struct Labrador : Dog {
    explicit Labrador(const std::string &_name, int _excitement = 9001)
        : Dog(_name, Kind::Labrador), excitement(_excitement) {}
    int excitement;
};

struct Chihuahua : Dog {
    explicit Chihuahua(const std::string &_name) : Dog(_name, Kind::Chihuahua) {
        sound = "iyiyiyiyiyi";
    }
    std::string bark() const { return Dog::bark() + " and runs in circles"; }
};

struct Cat : Animal {
    explicit Cat(const std::string &_name, Kind _kind = Kind::Cat) : Animal(_name, _kind) {}
    std::string purr() const { return "mrowr"; }
};

struct Panther : Cat {
    explicit Panther(const std::string &_name) : Cat(_name, Kind::Panther) {}
    std::string purr() const { return "mrrrRRRRRR"; }
};

std::vector<std::unique_ptr<Animal>> create_zoo() {
    std::vector<std::unique_ptr<Animal>> ret;
    ret.emplace_back(new Labrador("Fido", 15000));

    // simulate some new type of Dog that the Python bindings
    // haven't been updated for; it should still be considered
    // a Dog, not just an Animal.
    ret.emplace_back(new Dog("Ginger", Dog::Kind(150)));

    ret.emplace_back(new Chihuahua("Hertzl"));
    ret.emplace_back(new Cat("Tiger", Cat::Kind::Cat));
    ret.emplace_back(new Panther("Leo"));
    return ret;
}

const std::type_info *Animal::type_of_kind(Kind kind) {
    switch (kind) {
        case Kind::Unknown:
        case Kind::Dog:
            break;

        case Kind::Labrador:
            return &typeid(Labrador);
        case Kind::Chihuahua:
            return &typeid(Chihuahua);

        case Kind::LastDog:
        case Kind::Cat:
            break;
        case Kind::Panther:
            return &typeid(Panther);
        case Kind::LastCat:
            break;
    }

    if (kind >= Kind::Dog && kind <= Kind::LastDog) {
        return &typeid(Dog);
    }
    if (kind >= Kind::Cat && kind <= Kind::LastCat) {
        return &typeid(Cat);
    }
    return nullptr;
}

std::string Animal::name_of_kind(Kind kind) {
    std::string raw_name = type_of_kind(kind)->name();
    py::detail::clean_type_id(raw_name);
    return raw_name;
}

namespace PYBIND11_NAMESPACE {
template <typename itype>
struct polymorphic_type_hook<itype, detail::enable_if_t<std::is_base_of<Animal, itype>::value>> {
    static const void *get(const itype *src, const std::type_info *&type) {
        type = src ? Animal::type_of_kind(src->kind) : nullptr;
        return src;
    }
};
} // namespace PYBIND11_NAMESPACE

TEST_SUBMODULE(tagbased_polymorphic, m) {
    py::class_<Animal>(m, "Animal").def_readonly("name", &Animal::name);
    py::class_<Dog, Animal>(m, "Dog")
        .def(py::init<std::string>())
        .def_readwrite("sound", &Dog::sound)
        .def("bark", &Dog::bark);
    py::class_<Labrador, Dog>(m, "Labrador")
        .def(py::init<std::string, int>(), "name"_a, "excitement"_a = 9001)
        .def_readwrite("excitement", &Labrador::excitement);
    py::class_<Chihuahua, Dog>(m, "Chihuahua")
        .def(py::init<std::string>())
        .def("bark", &Chihuahua::bark);
    py::class_<Cat, Animal>(m, "Cat").def(py::init<std::string>()).def("purr", &Cat::purr);
    py::class_<Panther, Cat>(m, "Panther")
        .def(py::init<std::string>())
        .def("purr", &Panther::purr);
    m.def("create_zoo", &create_zoo);
};
