#pragma once

#include <array>
#include <cstdint>
#include <type_traits>

namespace JSON5EncoderCpp {
inline namespace {

template <class From>
constexpr std::uint32_t cast_to_uint32(
    const From &unsigned_from,
    typename std::enable_if<
        !std::is_signed<From>::value
    >::type* = nullptr
) {
    return static_cast<std::uint32_t>(unsigned_from);
}

template <class From>
constexpr std::uint32_t cast_to_uint32(
    const From &from,
    typename std::enable_if<
        std::is_signed<From>::value
    >::type* = nullptr
) {
    using UnsignedFrom = typename std::make_unsigned<From>::type;
    UnsignedFrom unsigned_from = static_cast<UnsignedFrom>(from);
    return cast_to_uint32(unsigned_from);
}

template <class From>
constexpr std::int32_t cast_to_int32(const From &from) {
    std::uint32_t unsigned_from = cast_to_uint32(from);
    return static_cast<std::int32_t>(unsigned_from);
}

struct AlwaysTrue {
    constexpr inline AlwaysTrue() = default;
    inline ~AlwaysTrue() = default;

    constexpr inline AlwaysTrue(const AlwaysTrue&) = default;
    constexpr inline AlwaysTrue(AlwaysTrue&&) = default;
    constexpr inline AlwaysTrue &operator =(const AlwaysTrue&) = default;
    constexpr inline AlwaysTrue &operator =(AlwaysTrue&&) = default;

    template <class T>
    constexpr inline AlwaysTrue(T&&) : AlwaysTrue() {}

    template <class T>
    constexpr inline bool operator ==(T&&) const { return true; }

    constexpr inline operator bool () const { return true; }
};

bool obj_has_iter(const PyObject *obj) {
    auto *i = Py_TYPE(obj)->tp_iter;
    return (i != nullptr) && (i != &_PyObject_NextNotImplemented);
}

struct EscapeDct {
    using Item = std::array<char, 8>;  // 7 are needed, 1 length
    static constexpr std::size_t length = 0x10000;

    Item items[length];
    unsigned __int128 is_escaped_array;

    static constexpr Item unicode_item(size_t index) {
        constexpr char HEX[] = "0123456789abcdef";
        return {{
            '\\',
            'u',
            HEX[(index / 16 / 16 / 16 % 16)],
            HEX[(index / 16 / 16      % 16)],
            HEX[(index / 16           % 16)],
            HEX[(index                % 16)],
            0,
            6,
        }};
    }

    static constexpr Item escaped_item(char chr) {
        return {{ '\\', chr, 0, 0, 0, 0, 0, 2 }};
    }

    static constexpr Item verbatim_item(size_t chr) {
        return {{ (char) (unsigned char) chr, 0, 0, 0, 0, 0, 0, 1 }};
    }

    inline bool is_escaped(uint32_t c) const {
        return (c >= 0x0080) || (is_escaped_array & (
            static_cast<unsigned __int128>(1) <<
            static_cast<std::uint8_t>(c)
        ));
    }

    inline std::size_t find_unescaped_range(const char *start, Py_ssize_t length) const {
        Py_ssize_t index = 0;
        while ((index < length) && !is_escaped(start[index])) {
            ++index;
        }
        return index;
    }

    constexpr EscapeDct() :
        items(),
        is_escaped_array(static_cast<unsigned __int128>(0) - 1)
    {
        for (std::size_t i = 0; i < length; ++i) {
            items[i] = unicode_item(i);
        }
        for (std::size_t i = 0x20; i < 0x7f; ++i) {
            switch (i) {
                case '"': case '\'': case '&': case '<': case '>': case '\\':
                    break;
                default:
                    items[i] = verbatim_item(i);

                    is_escaped_array &= ~(
                        static_cast<unsigned __int128>(1) <<
                        static_cast<std::uint8_t>(i)
                    );
            }
        }
        items[(uint8_t) '\\'] = escaped_item('\\');
        items[(uint8_t) '\b'] = escaped_item('b');
        items[(uint8_t) '\f'] = escaped_item('f');
        items[(uint8_t) '\n'] = escaped_item('n');
        items[(uint8_t) '\r'] = escaped_item('r');
        items[(uint8_t) '\t'] = escaped_item('t');
    }
};

const EscapeDct ESCAPE_DCT;

const char VERSION[] =
#   include "./VERSION"
;
static constexpr std::size_t VERSION_LENGTH = sizeof(VERSION) - 1;

const char LONGDESCRIPTION[] =
#   include "./VERSION"
;
static constexpr std::size_t LONGDESCRIPTION_LENGTH = sizeof(LONGDESCRIPTION) - 1;

}
}
