/*
    tests/test_stl.cpp -- STL type casters

    Copyright (c) 2017 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 <pybind11/stl.h>

#ifndef PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL
#define PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL
#endif
#include <pybind11/stl/filesystem.h>

#include <vector>
#include <string>

#if defined(PYBIND11_TEST_BOOST)
#include <boost/optional.hpp>

namespace pybind11 { namespace detail {
template <typename T>
struct type_caster<boost::optional<T>> : optional_caster<boost::optional<T>> {};

template <>
struct type_caster<boost::none_t> : void_caster<boost::none_t> {};
}} // namespace pybind11::detail
#endif

// Test with `std::variant` in C++17 mode, or with `boost::variant` in C++11/14
#if defined(PYBIND11_HAS_VARIANT)
using std::variant;
#elif defined(PYBIND11_TEST_BOOST) && (!defined(_MSC_VER) || _MSC_VER >= 1910)
#  include <boost/variant.hpp>
#  define PYBIND11_HAS_VARIANT 1
using boost::variant;

namespace pybind11 { namespace detail {
template <typename... Ts>
struct type_caster<boost::variant<Ts...>> : variant_caster<boost::variant<Ts...>> {};

template <>
struct visit_helper<boost::variant> {
    template <typename... Args>
    static auto call(Args &&...args) -> decltype(boost::apply_visitor(args...)) {
        return boost::apply_visitor(args...);
    }
};
}} // namespace pybind11::detail
#endif

PYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);

/// Issue #528: templated constructor
struct TplCtorClass {
    template <typename T>
    explicit TplCtorClass(const T &) {}
    bool operator==(const TplCtorClass &) const { return true; }
};

namespace std {
    template <>
    struct hash<TplCtorClass> { size_t operator()(const TplCtorClass &) const { return 0; } };
} // namespace std


template <template <typename> class OptionalImpl, typename T>
struct OptionalHolder
{
    // NOLINTNEXTLINE(modernize-use-equals-default): breaks GCC 4.8
    OptionalHolder() {};
    bool member_initialized() const {
        return member && member->initialized;
    }
    OptionalImpl<T> member = T{};
};


enum class EnumType {
  kSet = 42,
  kUnset = 85,
};

// This is used to test that return-by-ref and return-by-copy policies are
// handled properly for optional types. This is a regression test for a dangling
// reference issue. The issue seemed to require the enum value type to
// reproduce - it didn't seem to happen if the value type is just an integer.
template <template <typename> class OptionalImpl>
class OptionalProperties {
public:
    using OptionalEnumValue = OptionalImpl<EnumType>;

    OptionalProperties() : value(EnumType::kSet) {}
    ~OptionalProperties() {
        // Reset value to detect use-after-destruction.
        // This is set to a specific value rather than nullopt to ensure that
        // the memory that contains the value gets re-written.
        value = EnumType::kUnset;
    }

    OptionalEnumValue& access_by_ref() { return value; }
    OptionalEnumValue access_by_copy() { return value; }

private:
    OptionalEnumValue value;
};

// This type mimics aspects of boost::optional from old versions of Boost,
// which exposed a dangling reference bug in Pybind11. Recent versions of
// boost::optional, as well as libstdc++'s std::optional, don't seem to be
// affected by the same issue. This is meant to be a minimal implementation
// required to reproduce the issue, not fully standard-compliant.
// See issue #3330 for more details.
template <typename T>
class ReferenceSensitiveOptional {
public:
    using value_type = T;

    ReferenceSensitiveOptional() = default;
    // NOLINTNEXTLINE(google-explicit-constructor)
    ReferenceSensitiveOptional(const T& value) : storage{value} {}
    // NOLINTNEXTLINE(google-explicit-constructor)
    ReferenceSensitiveOptional(T&& value) : storage{std::move(value)} {}
    ReferenceSensitiveOptional& operator=(const T& value) {
        storage = {value};
        return *this;
    }
    ReferenceSensitiveOptional& operator=(T&& value) {
        storage = {std::move(value)};
        return *this;
    }

    template <typename... Args>
    T& emplace(Args&&... args) {
        storage.clear();
        storage.emplace_back(std::forward<Args>(args)...);
        return storage.back();
    }

    const T& value() const noexcept {
        assert(!storage.empty());
        return storage[0];
    }

    const T& operator*() const noexcept {
        return value();
    }

    const T* operator->() const noexcept {
        return &value();
    }

    explicit operator bool() const noexcept {
        return !storage.empty();
    }

private:
    std::vector<T> storage;
};

namespace pybind11 { namespace detail {
template <typename T>
struct type_caster<ReferenceSensitiveOptional<T>> : optional_caster<ReferenceSensitiveOptional<T>> {};
} // namespace detail
} // namespace pybind11


TEST_SUBMODULE(stl, m) {
    // test_vector
    m.def("cast_vector", []() { return std::vector<int>{1}; });
    m.def("load_vector", [](const std::vector<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });
    // `std::vector<bool>` is special because it returns proxy objects instead of references
    m.def("cast_bool_vector", []() { return std::vector<bool>{true, false}; });
    m.def("load_bool_vector", [](const std::vector<bool> &v) {
        return v.at(0) == true && v.at(1) == false;
    });
    // Unnumbered regression (caused by #936): pointers to stl containers aren't castable
    static std::vector<RValueCaster> lvv{2};
    m.def("cast_ptr_vector", []() { return &lvv; });

    // test_deque
    m.def("cast_deque", []() { return std::deque<int>{1}; });
    m.def("load_deque", [](const std::deque<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });

    // test_array
    m.def("cast_array", []() { return std::array<int, 2> {{1 , 2}}; });
    m.def("load_array", [](const std::array<int, 2> &a) { return a[0] == 1 && a[1] == 2; });

    // test_valarray
    m.def("cast_valarray", []() { return std::valarray<int>{1, 4, 9}; });
    m.def("load_valarray", [](const std::valarray<int>& v) {
        return v.size() == 3 && v[0] == 1 && v[1] == 4 && v[2] == 9;
    });

    // test_map
    m.def("cast_map", []() { return std::map<std::string, std::string>{{"key", "value"}}; });
    m.def("load_map", [](const std::map<std::string, std::string> &map) {
        return map.at("key") == "value" && map.at("key2") == "value2";
    });

    // test_set
    m.def("cast_set", []() { return std::set<std::string>{"key1", "key2"}; });
    m.def("load_set", [](const std::set<std::string> &set) {
        return (set.count("key1") != 0u) && (set.count("key2") != 0u) && (set.count("key3") != 0u);
    });

    // test_recursive_casting
    m.def("cast_rv_vector", []() { return std::vector<RValueCaster>{2}; });
    m.def("cast_rv_array", []() { return std::array<RValueCaster, 3>(); });
    // NB: map and set keys are `const`, so while we technically do move them (as `const Type &&`),
    // casters don't typically do anything with that, which means they fall to the `const Type &`
    // caster.
    m.def("cast_rv_map", []() { return std::unordered_map<std::string, RValueCaster>{{"a", RValueCaster{}}}; });
    m.def("cast_rv_nested", []() {
        std::vector<std::array<std::list<std::unordered_map<std::string, RValueCaster>>, 2>> v;
        v.emplace_back(); // add an array
        v.back()[0].emplace_back(); // add a map to the array
        v.back()[0].back().emplace("b", RValueCaster{});
        v.back()[0].back().emplace("c", RValueCaster{});
        v.back()[1].emplace_back(); // add a map to the array
        v.back()[1].back().emplace("a", RValueCaster{});
        return v;
    });
    static std::array<RValueCaster, 2> lva;
    static std::unordered_map<std::string, RValueCaster> lvm{{"a", RValueCaster{}}, {"b", RValueCaster{}}};
    static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>> lvn;
    lvn["a"].emplace_back(); // add a list
    lvn["a"].back().emplace_back(); // add an array
    lvn["a"].emplace_back(); // another list
    lvn["a"].back().emplace_back(); // add an array
    lvn["b"].emplace_back(); // add a list
    lvn["b"].back().emplace_back(); // add an array
    lvn["b"].back().emplace_back(); // add another array
    m.def("cast_lv_vector", []() -> const decltype(lvv) & { return lvv; });
    m.def("cast_lv_array", []() -> const decltype(lva) & { return lva; });
    m.def("cast_lv_map", []() -> const decltype(lvm) & { return lvm; });
    m.def("cast_lv_nested", []() -> const decltype(lvn) & { return lvn; });
    // #853:
    m.def("cast_unique_ptr_vector", []() {
        std::vector<std::unique_ptr<UserType>> v;
        v.emplace_back(new UserType{7});
        v.emplace_back(new UserType{42});
        return v;
    });

    pybind11::enum_<EnumType>(m, "EnumType")
        .value("kSet", EnumType::kSet)
        .value("kUnset", EnumType::kUnset);

    // test_move_out_container
    struct MoveOutContainer {
        struct Value { int value; };
        std::list<Value> move_list() const { return {{0}, {1}, {2}}; }
    };
    py::class_<MoveOutContainer::Value>(m, "MoveOutContainerValue")
        .def_readonly("value", &MoveOutContainer::Value::value);
    py::class_<MoveOutContainer>(m, "MoveOutContainer")
        .def(py::init<>())
        .def_property_readonly("move_list", &MoveOutContainer::move_list);

    // Class that can be move- and copy-constructed, but not assigned
    struct NoAssign {
        int value;

        explicit NoAssign(int value = 0) : value(value) { }
        NoAssign(const NoAssign &) = default;
        NoAssign(NoAssign &&) = default;

        NoAssign &operator=(const NoAssign &) = delete;
        NoAssign &operator=(NoAssign &&) = delete;
    };
    py::class_<NoAssign>(m, "NoAssign", "Class with no C++ assignment operators")
        .def(py::init<>())
        .def(py::init<int>());


    struct MoveOutDetector
    {
        MoveOutDetector() = default;
        MoveOutDetector(const MoveOutDetector&) = default;
        MoveOutDetector(MoveOutDetector&& other) noexcept
         : initialized(other.initialized) {
            // steal underlying resource
            other.initialized = false;
        }
        bool initialized = true;
    };
    py::class_<MoveOutDetector>(m, "MoveOutDetector", "Class with move tracking")
        .def(py::init<>())
        .def_readonly("initialized", &MoveOutDetector::initialized);


#ifdef PYBIND11_HAS_OPTIONAL
    // test_optional
    m.attr("has_optional") = true;

    using opt_int = std::optional<int>;
    using opt_no_assign = std::optional<NoAssign>;
    m.def("double_or_zero", [](const opt_int& x) -> int {
        return x.value_or(0) * 2;
    });
    m.def("half_or_none", [](int x) -> opt_int { return x != 0 ? opt_int(x / 2) : opt_int(); });
    m.def("test_nullopt", [](opt_int x) {
        return x.value_or(42);
    }, py::arg_v("x", std::nullopt, "None"));
    m.def("test_no_assign", [](const opt_no_assign &x) {
        return x ? x->value : 42;
    }, py::arg_v("x", std::nullopt, "None"));

    m.def("nodefer_none_optional", [](std::optional<int>) { return true; });
    m.def("nodefer_none_optional", [](const py::none &) { return false; });

    using opt_holder = OptionalHolder<std::optional, MoveOutDetector>;
    py::class_<opt_holder>(m, "OptionalHolder", "Class with optional member")
        .def(py::init<>())
        .def_readonly("member", &opt_holder::member)
        .def("member_initialized", &opt_holder::member_initialized);

    using opt_props = OptionalProperties<std::optional>;
    pybind11::class_<opt_props>(m, "OptionalProperties")
        .def(pybind11::init<>())
        .def_property_readonly("access_by_ref", &opt_props::access_by_ref)
        .def_property_readonly("access_by_copy", &opt_props::access_by_copy);
#endif

#ifdef PYBIND11_HAS_EXP_OPTIONAL
    // test_exp_optional
    m.attr("has_exp_optional") = true;

    using exp_opt_int = std::experimental::optional<int>;
    using exp_opt_no_assign = std::experimental::optional<NoAssign>;
    m.def("double_or_zero_exp", [](const exp_opt_int& x) -> int {
        return x.value_or(0) * 2;
    });
    m.def("half_or_none_exp", [](int x) -> exp_opt_int {
        return x ? exp_opt_int(x / 2) : exp_opt_int();
    });
    m.def("test_nullopt_exp", [](exp_opt_int x) {
        return x.value_or(42);
    }, py::arg_v("x", std::experimental::nullopt, "None"));
    m.def("test_no_assign_exp", [](const exp_opt_no_assign &x) {
        return x ? x->value : 42;
    }, py::arg_v("x", std::experimental::nullopt, "None"));

    using opt_exp_holder = OptionalHolder<std::experimental::optional, MoveOutDetector>;
    py::class_<opt_exp_holder>(m, "OptionalExpHolder", "Class with optional member")
        .def(py::init<>())
        .def_readonly("member", &opt_exp_holder::member)
        .def("member_initialized", &opt_exp_holder::member_initialized);

    using opt_exp_props = OptionalProperties<std::experimental::optional>;
    pybind11::class_<opt_exp_props>(m, "OptionalExpProperties")
        .def(pybind11::init<>())
        .def_property_readonly("access_by_ref", &opt_exp_props::access_by_ref)
        .def_property_readonly("access_by_copy", &opt_exp_props::access_by_copy);
#endif

#if defined(PYBIND11_TEST_BOOST)
    // test_boost_optional
    m.attr("has_boost_optional") = true;

    using boost_opt_int = boost::optional<int>;
    using boost_opt_no_assign = boost::optional<NoAssign>;
    m.def("double_or_zero_boost", [](const boost_opt_int& x) -> int {
        return x.value_or(0) * 2;
    });
    m.def("half_or_none_boost", [](int x) -> boost_opt_int {
        return x != 0 ? boost_opt_int(x / 2) : boost_opt_int();
    });
    m.def("test_nullopt_boost", [](boost_opt_int x) {
        return x.value_or(42);
    }, py::arg_v("x", boost::none, "None"));
    m.def("test_no_assign_boost", [](const boost_opt_no_assign &x) {
        return x ? x->value : 42;
    }, py::arg_v("x", boost::none, "None"));

    using opt_boost_holder = OptionalHolder<boost::optional, MoveOutDetector>;
    py::class_<opt_boost_holder>(m, "OptionalBoostHolder", "Class with optional member")
        .def(py::init<>())
        .def_readonly("member", &opt_boost_holder::member)
        .def("member_initialized", &opt_boost_holder::member_initialized);

    using opt_boost_props = OptionalProperties<boost::optional>;
    pybind11::class_<opt_boost_props>(m, "OptionalBoostProperties")
        .def(pybind11::init<>())
        .def_property_readonly("access_by_ref", &opt_boost_props::access_by_ref)
        .def_property_readonly("access_by_copy", &opt_boost_props::access_by_copy);
#endif

    // test_refsensitive_optional
    using refsensitive_opt_int = ReferenceSensitiveOptional<int>;
    using refsensitive_opt_no_assign = ReferenceSensitiveOptional<NoAssign>;
    m.def("double_or_zero_refsensitive", [](const refsensitive_opt_int& x) -> int {
        return (x ? x.value() : 0) * 2;
    });
    m.def("half_or_none_refsensitive", [](int x) -> refsensitive_opt_int {
        return x != 0 ? refsensitive_opt_int(x / 2) : refsensitive_opt_int();
    });
    // NOLINTNEXTLINE(performance-unnecessary-value-param)
    m.def("test_nullopt_refsensitive", [](refsensitive_opt_int x) {
        return x ? x.value() : 42;
    }, py::arg_v("x", refsensitive_opt_int(), "None"));
    m.def("test_no_assign_refsensitive", [](const refsensitive_opt_no_assign &x) {
        return x ? x->value : 42;
    }, py::arg_v("x", refsensitive_opt_no_assign(), "None"));

    using opt_refsensitive_holder = OptionalHolder<ReferenceSensitiveOptional, MoveOutDetector>;
    py::class_<opt_refsensitive_holder>(m, "OptionalRefSensitiveHolder", "Class with optional member")
        .def(py::init<>())
        .def_readonly("member", &opt_refsensitive_holder::member)
        .def("member_initialized", &opt_refsensitive_holder::member_initialized);

    using opt_refsensitive_props = OptionalProperties<ReferenceSensitiveOptional>;
    pybind11::class_<opt_refsensitive_props>(m, "OptionalRefSensitiveProperties")
        .def(pybind11::init<>())
        .def_property_readonly("access_by_ref", &opt_refsensitive_props::access_by_ref)
        .def_property_readonly("access_by_copy", &opt_refsensitive_props::access_by_copy);

#ifdef PYBIND11_HAS_FILESYSTEM
    // test_fs_path
    m.attr("has_filesystem") = true;
    m.def("parent_path", [](const std::filesystem::path& p) { return p.parent_path(); });
#endif

#ifdef PYBIND11_HAS_VARIANT
    static_assert(std::is_same<py::detail::variant_caster_visitor::result_type, py::handle>::value,
                  "visitor::result_type is required by boost::variant in C++11 mode");

    struct visitor {
        using result_type = const char *;

        result_type operator()(int) { return "int"; }
        result_type operator()(const std::string &) { return "std::string"; }
        result_type operator()(double) { return "double"; }
        result_type operator()(std::nullptr_t) { return "std::nullptr_t"; }
    };

    // test_variant
    m.def("load_variant", [](const variant<int, std::string, double, std::nullptr_t> &v) {
        return py::detail::visit_helper<variant>::call(visitor(), v);
    });
    m.def("load_variant_2pass", [](variant<double, int> v) {
        return py::detail::visit_helper<variant>::call(visitor(), v);
    });
    m.def("cast_variant", []() {
        using V = variant<int, std::string>;
        return py::make_tuple(V(5), V("Hello"));
    });
#endif

    // #528: templated constructor
    // (no python tests: the test here is that this compiles)
    m.def("tpl_ctor_vector", [](std::vector<TplCtorClass> &) {});
    m.def("tpl_ctor_map", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});
    m.def("tpl_ctor_set", [](std::unordered_set<TplCtorClass> &) {});
#if defined(PYBIND11_HAS_OPTIONAL)
    m.def("tpl_constr_optional", [](std::optional<TplCtorClass> &) {});
#endif
#if defined(PYBIND11_HAS_EXP_OPTIONAL)
    m.def("tpl_constr_optional_exp", [](std::experimental::optional<TplCtorClass> &) {});
#endif
#if defined(PYBIND11_TEST_BOOST)
    m.def("tpl_constr_optional_boost", [](boost::optional<TplCtorClass> &) {});
#endif

    // test_vec_of_reference_wrapper
    // #171: Can't return STL structures containing reference wrapper
    m.def("return_vec_of_reference_wrapper", [](std::reference_wrapper<UserType> p4) {
        static UserType p1{1}, p2{2}, p3{3};
        return std::vector<std::reference_wrapper<UserType>> {
            std::ref(p1), std::ref(p2), std::ref(p3), p4
        };
    });

    // test_stl_pass_by_pointer
    m.def("stl_pass_by_pointer", [](std::vector<int>* v) { return *v; }, "v"_a=nullptr);

    // #1258: pybind11/stl.h converts string to vector<string>
    m.def("func_with_string_or_vector_string_arg_overload",
          [](const std::vector<std::string> &) { return 1; });
    m.def("func_with_string_or_vector_string_arg_overload",
          [](const std::list<std::string> &) { return 2; });
    m.def("func_with_string_or_vector_string_arg_overload", [](const std::string &) { return 3; });

    class Placeholder {
    public:
        Placeholder() { print_created(this); }
        Placeholder(const Placeholder &) = delete;
        ~Placeholder() { print_destroyed(this); }
    };
    py::class_<Placeholder>(m, "Placeholder");

    /// test_stl_vector_ownership
    m.def("test_stl_ownership",
          []() {
              std::vector<Placeholder *> result;
              result.push_back(new Placeholder());
              return result;
          },
          py::return_value_policy::take_ownership);

    m.def("array_cast_sequence", [](std::array<int, 3> x) { return x; });

    /// test_issue_1561
    struct Issue1561Inner { std::string data; };
    struct Issue1561Outer { std::vector<Issue1561Inner> list; };

    py::class_<Issue1561Inner>(m, "Issue1561Inner")
        .def(py::init<std::string>())
        .def_readwrite("data", &Issue1561Inner::data);

    py::class_<Issue1561Outer>(m, "Issue1561Outer")
        .def(py::init<>())
        .def_readwrite("list", &Issue1561Outer::list);

    m.def(
        "return_vector_bool_raw_ptr",
        []() { return new std::vector<bool>(4513); },
        // Without explicitly specifying `take_ownership`, this function leaks.
        py::return_value_policy::take_ownership);
}
