/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *  Copyright (C) 2018  David Shah <david@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#ifndef COMMON_PYCONTAINERS_H
#define COMMON_PYCONTAINERS_H

#include <boost/python.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <sstream>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include "nextpnr.h"
#include "pywrappers.h"

NEXTPNR_NAMESPACE_BEGIN

using namespace boost::python;

inline void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); }

/*
A wrapper for a Pythonised nextpnr Iterator. The actual class wrapped is a
pair<Iterator, Iterator> containing (current, end), wrapped in a ContextualWrapper

*/

template <typename T, typename P, typename value_conv = PythonConversion::pass_through<T>> struct iterator_wrapper
{
    typedef decltype(*(std::declval<T>())) value_t;

    typedef PythonConversion::ContextualWrapper<std::pair<T, T>> wrapped_iter_t;
    using return_t = typename value_conv::ret_type;

    static return_t next(wrapped_iter_t &iter)
    {
        if (iter.base.first != iter.base.second) {
            return_t val = value_conv()(iter.ctx, *iter.base.first);
            ++iter.base.first;
            return val;
        } else {
            PyErr_SetString(PyExc_StopIteration, "End of range reached");
            boost::python::throw_error_already_set();
            // Should be unreachable, but prevent control may reach end of
            // non-void
            throw std::runtime_error("unreachable");
        }
    }

    static void wrap(const char *python_name)
    {
        class_<wrapped_iter_t>(python_name, no_init).def("__next__", next, P());
    }
};

/*
A wrapper for a nextpnr Range. Ranges should have two functions, begin()
and end() which return iterator-like objects supporting ++, * and !=
Full STL iterator semantics are not required, unlike the standard Boost wrappers
*/

template <typename T, typename P = return_value_policy<return_by_value>,
          typename value_conv = PythonConversion::pass_through<T>>
struct range_wrapper
{
    typedef decltype(std::declval<T>().begin()) iterator_t;
    typedef decltype(*(std::declval<iterator_t>())) value_t;
    typedef typename PythonConversion::ContextualWrapper<T> wrapped_range;
    typedef typename PythonConversion::ContextualWrapper<std::pair<iterator_t, iterator_t>> wrapped_pair;
    static wrapped_pair iter(wrapped_range &range)
    {
        return wrapped_pair(range.ctx, std::make_pair(range.base.begin(), range.base.end()));
    }

    static std::string repr(wrapped_range &range)
    {
        PythonConversion::string_converter<value_t> conv;
        bool first = true;
        std::stringstream ss;
        ss << "[";
        for (const auto &item : range.base) {
            if (!first)
                ss << ", ";
            ss << "'" << conv.to_str(range.ctx, item) << "'";
            first = false;
        }
        ss << "]";
        return ss.str();
    }

    static void wrap(const char *range_name, const char *iter_name)
    {
        class_<wrapped_range>(range_name, no_init).def("__iter__", iter).def("__repr__", repr);
        iterator_wrapper<iterator_t, P, value_conv>().wrap(iter_name);
    }

    typedef iterator_wrapper<iterator_t, P, value_conv> iter_wrap;
};

#define WRAP_RANGE(t, conv)                                                                                            \
    range_wrapper<t##Range, return_value_policy<return_by_value>, conv>().wrap(#t "Range", #t "Iterator")

/*
A wrapper for a vector or similar structure. With support for conversion
*/

template <typename T, typename P = return_value_policy<return_by_value>,
          typename value_conv = PythonConversion::pass_through<T>>
struct vector_wrapper
{
    typedef decltype(std::declval<T>().begin()) iterator_t;
    typedef decltype(*(std::declval<iterator_t>())) value_t;
    typedef typename PythonConversion::ContextualWrapper<T &> wrapped_vector;
    typedef typename PythonConversion::ContextualWrapper<std::pair<iterator_t, iterator_t>> wrapped_pair;
    using return_t = typename value_conv::ret_type;
    static wrapped_pair iter(wrapped_vector &range)
    {
        return wrapped_pair(range.ctx, std::make_pair(range.base.begin(), range.base.end()));
    }

    static std::string repr(wrapped_vector &range)
    {
        PythonConversion::string_converter<value_t> conv;
        bool first = true;
        std::stringstream ss;
        ss << "[";
        for (const auto &item : range.base) {
            if (!first)
                ss << ", ";
            ss << "'" << conv.to_str(range.ctx, item) << "'";
            first = false;
        }
        ss << "]";
        return ss.str();
    }

    static int len(wrapped_vector &range) { return range.base.size(); }

    static return_t getitem(wrapped_vector &range, int i)
    {
        return value_conv()(range.ctx, boost::ref(range.base.at(i)));
    }

    static void wrap(const char *range_name, const char *iter_name)
    {
        class_<wrapped_vector>(range_name, no_init)
                .def("__iter__", iter)
                .def("__repr__", repr)
                .def("__len__", len)
                .def("__getitem__", getitem);

        iterator_wrapper<iterator_t, P, value_conv>().wrap(iter_name);
    }

    typedef iterator_wrapper<iterator_t, P, value_conv> iter_wrap;
};

#define WRAP_VECTOR(t, conv) vector_wrapper<t, return_value_policy<return_by_value>, conv>().wrap(#t, #t "Iterator")

/*
Wrapper for a pair, allows accessing either using C++-style members (.first and
.second) or as a Python iterable and indexable object
*/
template <typename T1, typename T2> struct pair_wrapper
{
    typedef std::pair<T1, T2> T;

    struct pair_iterator_wrapper
    {
        static object next(std::pair<T &, int> &iter)
        {
            if (iter.second == 0) {
                iter.second++;
                return object(iter.first.first);
            } else if (iter.second == 1) {
                iter.second++;
                return object(iter.first.second);
            } else {
                PyErr_SetString(PyExc_StopIteration, "End of range reached");
                boost::python::throw_error_already_set();
                // Should be unreachable, but prevent control may reach end of
                // non-void
                throw std::runtime_error("unreachable");
            }
        }

        static void wrap(const char *python_name)
        {
            class_<std::pair<T &, int>>(python_name, no_init).def("__next__", next);
        }
    };

    static object get(T &x, int i)
    {
        if ((i >= 2) || (i < 0))
            KeyError();
        return (i == 1) ? object(x.second) : object(x.first);
    }

    static void set(T &x, int i, object val)
    {
        if ((i >= 2) || (i < 0))
            KeyError();
        if (i == 0)
            x.first = extract<T1>(val);
        if (i == 1)
            x.second = extract<T2>(val);
    }

    static int len(T &x) { return 2; }

    static std::pair<T &, int> iter(T &x) { return std::make_pair(boost::ref(x), 0); };

    static void wrap(const char *pair_name, const char *iter_name)
    {
        pair_iterator_wrapper::wrap(iter_name);
        class_<T>(pair_name, no_init)
                .def("__iter__", iter)
                .def("__len__", len)
                .def("__getitem__", get)
                .def("__setitem__", set, with_custodian_and_ward<1, 2>())
                .def_readwrite("first", &T::first)
                .def_readwrite("second", &T::second);
    }
};

/*
Special case of above for map key/values
 */
template <typename T1, typename T2, typename value_conv> struct map_pair_wrapper
{
    typedef std::pair<T1, T2> T;
    typedef PythonConversion::ContextualWrapper<T &> wrapped_pair;
    typedef typename T::second_type V;

    struct pair_iterator_wrapper
    {
        static object next(std::pair<wrapped_pair &, int> &iter)
        {
            if (iter.second == 0) {
                iter.second++;
                return object(PythonConversion::string_converter<decltype(iter.first.base.first)>().to_str(
                        iter.first.ctx, iter.first.base.first));
            } else if (iter.second == 1) {
                iter.second++;
                return object(value_conv()(iter.first.ctx, iter.first.base.second));
            } else {
                PyErr_SetString(PyExc_StopIteration, "End of range reached");
                boost::python::throw_error_already_set();
                // Should be unreachable, but prevent control may reach end of
                // non-void
                throw std::runtime_error("unreachable");
            }
        }

        static void wrap(const char *python_name)
        {
            class_<std::pair<wrapped_pair &, int>>(python_name, no_init).def("__next__", next);
        }
    };

    static object get(wrapped_pair &x, int i)
    {
        if ((i >= 2) || (i < 0))
            KeyError();
        return (i == 1) ? object(value_conv()(x.ctx, x.base.second)) : object(x.base.first);
    }

    static int len(wrapped_pair &x) { return 2; }

    static std::pair<wrapped_pair &, int> iter(wrapped_pair &x) { return std::make_pair(boost::ref(x), 0); };

    static std::string first_getter(wrapped_pair &t)
    {
        return PythonConversion::string_converter<decltype(t.base.first)>().to_str(t.ctx, t.base.first);
    }

    static typename value_conv::ret_type second_getter(wrapped_pair &t) { return value_conv()(t.ctx, t.base.second); }

    static void wrap(const char *pair_name, const char *iter_name)
    {
        pair_iterator_wrapper::wrap(iter_name);
        class_<wrapped_pair>(pair_name, no_init)
                .def("__iter__", iter)
                .def("__len__", len)
                .def("__getitem__", get)
                .add_property("first", first_getter)
                .add_property("second", second_getter);
    }
};

/*
Wrapper for a map, either an unordered_map, regular map or dict
 */

template <typename T, typename value_conv> struct map_wrapper
{
    typedef typename std::remove_cv<typename std::remove_reference<typename T::key_type>::type>::type K;
    typedef typename T::mapped_type V;
    typedef typename value_conv::ret_type wrapped_V;
    typedef typename T::value_type KV;
    typedef typename PythonConversion::ContextualWrapper<T &> wrapped_map;

    static wrapped_V get(wrapped_map &x, std::string const &i)
    {
        K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
        if (x.base.find(k) != x.base.end())
            return value_conv()(x.ctx, x.base.at(k));
        KeyError();
        std::terminate();
    }

    static void set(wrapped_map &x, std::string const &i, V const &v)
    {
        x.base[PythonConversion::string_converter<K>().from_str(x.ctx, i)] = v;
    }

    static size_t len(wrapped_map &x) { return x.base.size(); }

    static void del(T const &x, std::string const &i)
    {
        K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
        if (x.base.find(k) != x.base.end())
            x.base.erase(k);
        else
            KeyError();
        std::terminate();
    }

    static bool contains(wrapped_map &x, std::string const &i)
    {
        K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
        return x.base.count(k);
    }

    static void wrap(const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name)
    {
        map_pair_wrapper<typename KV::first_type, typename KV::second_type, value_conv>::wrap(kv_name, kv_iter_name);
        typedef range_wrapper<T &, return_value_policy<return_by_value>, PythonConversion::wrap_context<KV &>> rw;
        typename rw::iter_wrap().wrap(iter_name);
        class_<wrapped_map>(map_name, no_init)
                .def("__iter__", rw::iter)
                .def("__len__", len)
                .def("__contains__", contains)
                .def("__getitem__", get)
                .def("__setitem__", set, with_custodian_and_ward<1, 2>());
    }
};

/*
Special case of above for map key/values where value is a unique_ptr
 */
template <typename T1, typename T2> struct map_pair_wrapper_uptr
{
    typedef std::pair<T1, T2> T;
    typedef PythonConversion::ContextualWrapper<T &> wrapped_pair;
    typedef typename T::second_type::element_type V;

    struct pair_iterator_wrapper
    {
        static object next(std::pair<wrapped_pair &, int> &iter)
        {
            if (iter.second == 0) {
                iter.second++;
                return object(PythonConversion::string_converter<decltype(iter.first.base.first)>().to_str(
                        iter.first.ctx, iter.first.base.first));
            } else if (iter.second == 1) {
                iter.second++;
                return object(PythonConversion::ContextualWrapper<V &>(iter.first.ctx, *iter.first.base.second.get()));
            } else {
                PyErr_SetString(PyExc_StopIteration, "End of range reached");
                boost::python::throw_error_already_set();
                // Should be unreachable, but prevent control may reach end of
                // non-void
                throw std::runtime_error("unreachable");
            }
        }

        static void wrap(const char *python_name)
        {
            class_<std::pair<wrapped_pair &, int>>(python_name, no_init).def("__next__", next);
        }
    };

    static object get(wrapped_pair &x, int i)
    {
        if ((i >= 2) || (i < 0))
            KeyError();
        return (i == 1) ? object(PythonConversion::ContextualWrapper<V &>(x.ctx, *x.base.second.get()))
                        : object(x.base.first);
    }

    static int len(wrapped_pair &x) { return 2; }

    static std::pair<wrapped_pair &, int> iter(wrapped_pair &x) { return std::make_pair(boost::ref(x), 0); };

    static std::string first_getter(wrapped_pair &t)
    {
        return PythonConversion::string_converter<decltype(t.base.first)>().to_str(t.ctx, t.base.first);
    }

    static PythonConversion::ContextualWrapper<V &> second_getter(wrapped_pair &t)
    {
        return PythonConversion::ContextualWrapper<V &>(t.ctx, *t.base.second.get());
    }

    static void wrap(const char *pair_name, const char *iter_name)
    {
        pair_iterator_wrapper::wrap(iter_name);
        class_<wrapped_pair>(pair_name, no_init)
                .def("__iter__", iter)
                .def("__len__", len)
                .def("__getitem__", get)
                .add_property("first", first_getter)
                .add_property("second", second_getter);
    }
};

/*
Wrapper for a map, either an unordered_map, regular map or dict
 */

template <typename T> struct map_wrapper_uptr
{
    typedef typename std::remove_cv<typename std::remove_reference<typename T::key_type>::type>::type K;
    typedef typename T::mapped_type::pointer V;
    typedef typename T::mapped_type::element_type &Vr;
    typedef typename T::value_type KV;
    typedef typename PythonConversion::ContextualWrapper<T &> wrapped_map;

    static PythonConversion::ContextualWrapper<Vr> get(wrapped_map &x, std::string const &i)
    {
        K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
        if (x.base.find(k) != x.base.end())
            return PythonConversion::ContextualWrapper<Vr>(x.ctx, *x.base.at(k).get());
        KeyError();
        std::terminate();
    }

    static void set(wrapped_map &x, std::string const &i, V const &v)
    {
        x.base[PythonConversion::string_converter<K>().from_str(x.ctx, i)] = typename T::mapped_type(v);
    }

    static size_t len(wrapped_map &x) { return x.base.size(); }

    static void del(T const &x, std::string const &i)
    {
        K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
        if (x.base.find(k) != x.base.end())
            x.base.erase(k);
        else
            KeyError();
        std::terminate();
    }

    static bool contains(wrapped_map &x, std::string const &i)
    {
        K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
        return x.base.count(k);
    }

    static void wrap(const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name)
    {
        map_pair_wrapper_uptr<typename KV::first_type, typename KV::second_type>::wrap(kv_name, kv_iter_name);
        typedef range_wrapper<T &, return_value_policy<return_by_value>, PythonConversion::wrap_context<KV &>> rw;
        typename rw::iter_wrap().wrap(iter_name);
        class_<wrapped_map>(map_name, no_init)
                .def("__iter__", rw::iter)
                .def("__len__", len)
                .def("__contains__", contains)
                .def("__getitem__", get)
                .def("__setitem__", set, with_custodian_and_ward<1, 2>());
    }
};

#define WRAP_MAP(t, conv, name)                                                                                        \
    map_wrapper<t, conv>().wrap(#name, #name "KeyValue", #name "KeyValueIter", #name "Iterator")
#define WRAP_MAP_UPTR(t, name)                                                                                         \
    map_wrapper_uptr<t>().wrap(#name, #name "KeyValue", #name "KeyValueIter", #name "Iterator")

NEXTPNR_NAMESPACE_END

#endif
