#pragma once
#include <fmt/format.h>
#include <stdexcept>
#include <stdplus/types.hpp>
#include <string_view>
#include <type_traits>

namespace stdplus
{
namespace raw
{

namespace detail
{

/** @brief Gets the datatype referenced in a container
 */
template <typename Container>
using dataType = std::remove_pointer_t<decltype(
    std::data(std::declval<std::add_lvalue_reference_t<Container>>()))>;

/** @brief Determines if the container holds trivially copyable data
 */
template <typename Container>
inline constexpr bool trivialContainer =
    std::is_trivially_copyable_v<dataType<Container>>;

/** @brief Adds const to A if B is const
 */
template <typename A, typename B>
using copyConst =
    std::conditional_t<std::is_const_v<B>, std::add_const_t<A>, A>;

/** @brief Determines if a type is a container of data
 */
template <typename, typename = void>
inline constexpr bool hasData = false;
template <typename T>
inline constexpr bool hasData<T, std::void_t<dataType<T>>> = true;

} // namespace detail

/** @brief Compares two containers to see if their raw bytes are equal
 *
 *  @param[in] a - The first container
 *  @param[in] b - The second container
 *  @return True if they are the same, false otherwise
 */
template <typename A, typename B>
bool equal(const A& a, const B& b) noexcept
{
    static_assert(std::is_trivially_copyable_v<A>);
    static_assert(std::is_trivially_copyable_v<B>);
    static_assert(sizeof(A) == sizeof(B));
    return memcmp(&a, &b, sizeof(A)) == 0;
}

/** @brief Copies data from a buffer into a copyable type
 *
 *  @param[in] data - The data buffer being copied from
 *  @return The copyable type with data populated
 */
template <typename T, typename Container>
T copyFrom(const Container& c)
{
    static_assert(std::is_trivially_copyable_v<T>);
    static_assert(detail::trivialContainer<Container>);
    T ret;
    const size_t bytes = std::size(c) * sizeof(*std::data(c));
    if (bytes < sizeof(ret))
    {
        throw std::runtime_error(
            fmt::format("CopyFrom: {} < {}", bytes, sizeof(ret)));
    }
    std::memcpy(&ret, std::data(c), sizeof(ret));
    return ret;
}

/** @brief References the data from a buffer if aligned
 *
 *  @param[in] data - The data buffer being referenced
 *  @return The reference to the data in the new type
 */
template <typename T, typename Container,
          typename Tp = detail::copyConst<T, detail::dataType<Container>>>
Tp& refFrom(Container&& c)
{
    static_assert(std::is_trivially_copyable_v<Tp>);
    static_assert(detail::trivialContainer<Container>);
    static_assert(sizeof(*std::data(c)) % alignof(Tp) == 0);
    const size_t bytes = std::size(c) * sizeof(*std::data(c));
    if (bytes < sizeof(Tp))
    {
        throw std::runtime_error(
            fmt::format("RefFrom: {} < {}", bytes, sizeof(Tp)));
    }
    return *reinterpret_cast<Tp*>(std::data(c));
}

/** @brief Extracts data from a buffer into a copyable type
 *         Updates the data buffer to show that data was removed
 *
 *  @param[in,out] data - The data buffer being extracted from
 *  @return The copyable type with data populated
 */
template <typename T, typename CharT>
T extract(std::basic_string_view<CharT>& data)
{
    T ret = copyFrom<T>(data);
    static_assert(sizeof(T) % sizeof(CharT) == 0);
    data.remove_prefix(sizeof(T) / sizeof(CharT));
    return ret;
}
#ifdef STDPLUS_SPAN_TYPE
template <typename T, typename IntT,
          typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>>
T extract(span<IntT>& data)
{
    T ret = copyFrom<T>(data);
    static_assert(sizeof(T) % sizeof(IntT) == 0);
    data = data.subspan(sizeof(T) / sizeof(IntT));
    return ret;
}
#endif

/** @brief Extracts data from a buffer as a reference if aligned
 *         Updates the data buffer to show that data was removed
 *
 *  @param[in,out] data - The data buffer being extracted from
 *  @return A reference to the data
 */
template <typename T, typename CharT>
const T& extractRef(std::basic_string_view<CharT>& data)
{
    const T& ret = refFrom<T>(data);
    static_assert(sizeof(T) % sizeof(CharT) == 0);
    data.remove_prefix(sizeof(T) / sizeof(CharT));
    return ret;
}
#ifdef STDPLUS_SPAN_TYPE
template <typename T, typename IntT,
          typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>,
          typename Tp = detail::copyConst<T, IntT>>
Tp& extractRef(span<IntT>& data)
{
    Tp& ret = refFrom<Tp>(data);
    static_assert(sizeof(Tp) % sizeof(IntT) == 0);
    data = data.subspan(sizeof(Tp) / sizeof(IntT));
    return ret;
}
#endif

/** @brief Returns the span referencing the data of the raw trivial type
 *         or of trivial types in a contiguous container.
 *
 *  @param[in] t - The trivial raw data
 *  @return A view over the input with the given output integral type
 */
template <typename CharT, typename T>
std::enable_if_t<!detail::hasData<T>, std::basic_string_view<CharT>>
    asView(const T& t) noexcept
{
    static_assert(std::is_trivially_copyable_v<T>);
    static_assert(sizeof(T) % sizeof(CharT) == 0);
    return {reinterpret_cast<const CharT*>(&t), sizeof(T) / sizeof(CharT)};
}

template <typename CharT, typename Container>
std::enable_if_t<detail::hasData<Container>, std::basic_string_view<CharT>>
    asView(const Container& c) noexcept
{
    static_assert(detail::trivialContainer<Container>);
    static_assert(sizeof(*std::data(c)) % sizeof(CharT) == 0);
    return {reinterpret_cast<const CharT*>(std::data(c)),
            std::size(c) * sizeof(*std::data(c)) / sizeof(CharT)};
}

#ifdef STDPLUS_SPAN_TYPE
template <typename IntT, typename T,
          typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>,
          typename = std::enable_if_t<!detail::hasData<T>>,
          typename IntTp = detail::copyConst<IntT, T>>
span<IntTp> asSpan(T& t) noexcept
{
    static_assert(std::is_trivially_copyable_v<T>);
    static_assert(sizeof(T) % sizeof(IntTp) == 0);
    return {reinterpret_cast<IntTp*>(&t), sizeof(T) / sizeof(IntTp)};
}
template <typename IntT, typename Container,
          typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>,
          typename = std::enable_if_t<detail::hasData<Container>>,
          typename IntTp = detail::copyConst<IntT, detail::dataType<Container>>>
span<IntTp> asSpan(Container&& c) noexcept
{
    static_assert(detail::trivialContainer<Container>);
    static_assert(sizeof(*std::data(c)) % sizeof(IntTp) == 0);
    return {reinterpret_cast<IntTp*>(std::data(c)),
            std::size(c) * sizeof(*std::data(c)) / sizeof(IntTp)};
}
#endif

} // namespace raw
} // namespace stdplus
