#pragma once

#include <boost/spirit/home/x3.hpp>

#include <algorithm>
#include <cctype>
#include <iomanip>
#include <ostream>
#include <ranges>
#include <span>
#include <string>
#include <string_view>
#include <vector>

namespace http_helpers
{

enum class ContentType
{
    NoMatch,
    ANY, // Accepts: */*
    CBOR,
    HTML,
    JSON,
    OctetStream,
    EventStream,
};

inline ContentType getPreferredContentType(
    std::string_view header, std::span<const ContentType> preferredOrder)
{
    using boost::spirit::x3::char_;
    using boost::spirit::x3::lit;
    using boost::spirit::x3::omit;
    using boost::spirit::x3::parse;
    using boost::spirit::x3::space;
    using boost::spirit::x3::symbols;
    using boost::spirit::x3::uint_;

    const symbols<ContentType> knownMimeType{
        {"application/cbor", ContentType::CBOR},
        {"application/json", ContentType::JSON},
        {"application/octet-stream", ContentType::OctetStream},
        {"text/html", ContentType::HTML},
        {"text/event-stream", ContentType::EventStream},
        {"*/*", ContentType::ANY}};

    std::vector<ContentType> ct;

    auto parameters = *(lit(';') >> lit("q=") >> uint_ >> -(lit('.') >> uint_));
    auto typeCharset = char_("a-zA-Z.+-");
    auto mimeType = knownMimeType |
                    omit[+typeCharset >> lit('/') >> +typeCharset];
    auto parser = +(mimeType >> omit[parameters >> -char_(',') >> *space]);
    if (!parse(header.begin(), header.end(), parser, ct))
    {
        return ContentType::NoMatch;
    }

    for (const ContentType parsedType : ct)
    {
        if (parsedType == ContentType::ANY)
        {
            return parsedType;
        }
        auto it = std::ranges::find(preferredOrder, parsedType);
        if (it != preferredOrder.end())
        {
            return *it;
        }
    }

    return ContentType::NoMatch;
}

inline bool isContentTypeAllowed(std::string_view header, ContentType type,
                                 bool allowWildcard)
{
    auto types = std::to_array({type});
    ContentType allowed = getPreferredContentType(header, types);
    if (allowed == ContentType::ANY)
    {
        return allowWildcard;
    }

    return type == allowed;
}

enum class Encoding
{
    ParseError,
    NoMatch,
    UnencodedBytes,
    GZIP,
    ZSTD,
    ANY, // represents *. Never returned.  Only used for string matching
};

inline Encoding
    getPreferredEncoding(std::string_view acceptEncoding,
                         const std::span<const Encoding> availableEncodings)
{
    if (acceptEncoding.empty())
    {
        return Encoding::UnencodedBytes;
    }

    using boost::spirit::x3::char_;
    using boost::spirit::x3::lit;
    using boost::spirit::x3::omit;
    using boost::spirit::x3::parse;
    using boost::spirit::x3::space;
    using boost::spirit::x3::symbols;
    using boost::spirit::x3::uint_;

    const symbols<Encoding> knownAcceptEncoding{{"gzip", Encoding::GZIP},
                                                {"zstd", Encoding::ZSTD},
                                                {"*", Encoding::ANY}};

    std::vector<Encoding> ct;

    auto parameters = *(lit(';') >> lit("q=") >> uint_ >> -(lit('.') >> uint_));
    auto typeCharset = char_("a-zA-Z.+-");
    auto encodeType = knownAcceptEncoding | omit[+typeCharset];
    auto parser = +(encodeType >> omit[parameters >> -char_(',') >> *space]);
    if (!parse(acceptEncoding.begin(), acceptEncoding.end(), parser, ct))
    {
        return Encoding::ParseError;
    }

    for (const Encoding parsedType : ct)
    {
        if (parsedType == Encoding::ANY)
        {
            if (!availableEncodings.empty())
            {
                return *availableEncodings.begin();
            }
        }
        auto it = std::ranges::find(availableEncodings, parsedType);
        if (it != availableEncodings.end())
        {
            return *it;
        }
    }

    // Fall back to raw bytes if it was allowed
    auto it = std::ranges::find(availableEncodings, Encoding::UnencodedBytes);
    if (it != availableEncodings.end())
    {
        return *it;
    }

    return Encoding::NoMatch;
}

} // namespace http_helpers
