/*
 * Copyright 2019 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkZip_DEFINED
#define SkZip_DEFINED

#include <cstddef>
#include <iterator>
#include <tuple>
#include <type_traits>

#include "include/core/SkTypes.h"
#include "include/private/SkMacros.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkTo.h"
#include "src/core/SkSpan.h"

// Take a list of things that can be pointers, and use them all in parallel. The iterators and
// accessor operator[] for the class produce a tuple of the items.
template<typename... Ts>
class SkZip {
    using ReturnTuple = std::tuple<Ts&...>;

    class Iterator {
    public:
        using value_type = ReturnTuple;
        using difference_type = ptrdiff_t;
        using pointer = value_type*;
        using reference = value_type;
        using iterator_category = std::input_iterator_tag;
        constexpr Iterator(const SkZip* zip, size_t index) : fZip{zip}, fIndex{index} { }
        constexpr Iterator(const Iterator& that) : Iterator{ that.fZip, that.fIndex } { }
        CONSTEXPR Iterator& operator++() {
            ++fIndex;
            return *this;
        }
        CONSTEXPR Iterator operator++(int) {
            Iterator tmp(*this);
            operator++();
            return tmp;
        }
        constexpr bool operator==(const Iterator& rhs) const { return fIndex == rhs.fIndex; }
        constexpr bool operator!=(const Iterator& rhs) const { return fIndex != rhs.fIndex; }
        CONSTEXPR reference operator*() { return (*fZip)[fIndex]; }
        friend constexpr difference_type operator-(Iterator lhs, Iterator rhs) {
            return lhs.fIndex - rhs.fIndex;
        }

    private:
        const SkZip* const fZip = nullptr;
        size_t fIndex = 0;
    };

    template<typename T>
    using make_nullptr = std::integral_constant<std::nullptr_t, nullptr>;

public:
    constexpr SkZip() : fPointers{make_nullptr<Ts*>::value...}, fSize{0} {}
    constexpr SkZip(size_t) = delete;
    constexpr SkZip(size_t size, Ts*... ts)
            : fPointers{ts...}
            , fSize{size} {}
    constexpr SkZip(const SkZip& that) = default;

    // Check to see if U can be used for const T or is the same as T
    template <typename U, typename T>
    using CanConvertToConst = typename std::integral_constant<bool,
                    std::is_convertible<U*, T*>::value && sizeof(U) == sizeof(T)>::type;

    // Allow SkZip<const T> to be constructed from SkZip<T>.
    template<typename... Us,
            typename = std::enable_if<skstd::conjunction<CanConvertToConst<Us, Ts>...>::value>>
    constexpr SkZip(const SkZip<Us...>& that)
        : fPointers(that.data())
        , fSize{that.size()} { }

    constexpr ReturnTuple operator[](size_t i) const { return this->index(i);}
    constexpr size_t size() const { return fSize; }
    constexpr bool empty() const { return this->size() == 0; }
    constexpr ReturnTuple front() const { return this->index(0); }
    constexpr ReturnTuple back() const { return this->index(this->size() - 1); }
    constexpr Iterator begin() const { return Iterator{this, 0}; }
    constexpr Iterator end() const { return Iterator{this, this->size()}; }
    template <size_t I>
    constexpr SkSpan<typename std::tuple_element<I, std::tuple<Ts...>>::type> get() const {
        return SkMakeSpan(std::get<I>(fPointers), fSize);
    }
    constexpr std::tuple<Ts*...> data() const { return fPointers; }
    CONSTEXPR SkZip first(size_t n) const {
        SkASSERT(n <= this->size());
        return SkZip{n, fPointers};
    }

private:
    constexpr SkZip(size_t n, const std::tuple<Ts*...>& pointers)
        : fPointers{pointers}
        , fSize{n} {}

    CONSTEXPR ReturnTuple index(size_t i) const {
        SkASSERT(this->size() > 0);
        SkASSERT(i < this->size());
        return indexDetail(i, skstd::make_index_sequence<sizeof...(Ts)>{});
    }

    template<std::size_t... Is>
    constexpr ReturnTuple indexDetail(size_t i, skstd::index_sequence<Is...>) const {
        return ReturnTuple((std::get<Is>(fPointers))[i]...);
    }

    std::tuple<Ts*...> fPointers;
    size_t fSize;
};

class SkMakeZipDetail {
    template<typename T> struct DecayPointer{
        using U = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
        using type = typename std::conditional<std::is_pointer<U>::value, U, T>::type;
    };
    template<typename T> using DecayPointerT = typename DecayPointer<T>::type;

    template<typename C> struct ContiguousMemory { };
    template<typename T> struct ContiguousMemory<T*> {
        using value_type = T;
        static constexpr value_type* Data(T* t) { return t; }
        static constexpr size_t Size(T* s) { return SIZE_MAX; }
    };
    template<typename T, size_t N> struct ContiguousMemory<T(&)[N]> {
        using value_type = T;
        static constexpr value_type* Data(T(&t)[N]) { return t; }
        static constexpr size_t Size(T(&)[N]) { return N; }
    };
    // In general, we don't want r-value collections, but SkSpans are ok, because they are a view
    // onto an actual container.
    template<typename T> struct ContiguousMemory<SkSpan<T>> {
        using value_type = T;
        static constexpr value_type* Data(SkSpan<T> s) { return s.data(); }
        static constexpr size_t Size(SkSpan<T> s) { return s.size(); }
    };
    // Only accept l-value references to collections.
    template<typename C> struct ContiguousMemory<C&> {
        using value_type = typename std::remove_pointer<decltype(std::declval<C>().data())>::type;
        static constexpr value_type* Data(C& c) { return c.data(); }
        static constexpr size_t Size(C& c) { return c.size(); }
    };
    template<typename C> using Span = ContiguousMemory<DecayPointerT<C>>;
    template<typename C> using ValueType = typename Span<C>::value_type;

    template<typename C, typename... Ts> struct PickOneSize { };
    template <typename T, typename... Ts> struct PickOneSize<T*, Ts...> {
        static constexpr size_t Size(T* t, Ts... ts) {
            return PickOneSize<Ts...>::Size(std::forward<Ts>(ts)...);
        }
    };
    template <typename T, typename... Ts, size_t N> struct PickOneSize<T(&)[N], Ts...> {
        static constexpr size_t Size(T(&)[N], Ts...) { return N; }
    };
    template<typename T, typename... Ts> struct PickOneSize<SkSpan<T>, Ts...> {
        static constexpr size_t Size(SkSpan<T> s, Ts...) { return s.size(); }
    };
    template<typename C, typename... Ts> struct PickOneSize<C&, Ts...> {
        static constexpr size_t Size(C& c, Ts...) { return c.size(); }
    };

public:
    template <typename... Ts> static CONSTEXPR SkZip<ValueType<Ts>...> MakeZip(Ts&&... ts) {
        // Pick the first collection that has a size, and use that for the size.
        size_t size = PickOneSize<DecayPointerT<Ts>...>::Size(std::forward<Ts>(ts)...);

#ifdef SK_DEBUG
        // Check that all sizes are the same.
        size_t minSize = SIZE_MAX;
        size_t maxSize = 0;
        for (size_t s : {Span<Ts>::Size(std::forward<Ts>(ts))...}) {
            if (s != SIZE_MAX) {
                minSize = SkTMin(minSize, s);
                maxSize = SkTMax(maxSize, s);
            }
        }
        SkASSERT(minSize == maxSize);
#endif

        return SkZip<ValueType<Ts>...>{size, Span<Ts>::Data(std::forward<Ts>(ts))...};
    }
};

template <typename... Ts>
inline constexpr auto SkMakeZip(Ts&&... ts)
        -> decltype(SkMakeZipDetail::MakeZip(std::forward<Ts>(ts)...)) {
    return SkMakeZipDetail::MakeZip(std::forward<Ts>(ts)...);
}
#endif //SkZip_DEFINED
