#pragma once

#include "bmcweb_config.h"

extern "C"
{
#include <openssl/crypto.h>
}

#include <boost/callable_traits.hpp>
#include <boost/url/parse.hpp>
#include <boost/url/url.hpp>
#include <boost/url/url_view.hpp>
#include <boost/url/url_view_base.hpp>
#include <nlohmann/json.hpp>

#include <array>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <ctime>
#include <functional>
#include <iomanip>
#include <limits>
#include <stdexcept>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>

namespace crow
{
namespace utility
{

constexpr uint64_t getParameterTag(std::string_view url)
{
    uint64_t tagValue = 0;
    size_t urlSegmentIndex = std::string_view::npos;

    for (size_t urlIndex = 0; urlIndex < url.size(); urlIndex++)
    {
        char character = url[urlIndex];
        if (character == '<')
        {
            if (urlSegmentIndex != std::string_view::npos)
            {
                return 0;
            }
            urlSegmentIndex = urlIndex;
        }
        if (character == '>')
        {
            if (urlSegmentIndex == std::string_view::npos)
            {
                return 0;
            }
            std::string_view tag = url.substr(urlSegmentIndex,
                                              urlIndex + 1 - urlSegmentIndex);

            if (tag == "<str>" || tag == "<string>")
            {
                tagValue++;
            }
            if (tag == "<path>")
            {
                tagValue++;
            }
            urlSegmentIndex = std::string_view::npos;
        }
    }
    if (urlSegmentIndex != std::string_view::npos)
    {
        return 0;
    }
    return tagValue;
}

class Base64Encoder
{
    char overflow1 = '\0';
    char overflow2 = '\0';
    uint8_t overflowCount = 0;

    constexpr static std::array<char, 64> key = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
        'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
        'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};

    // Takes 3 ascii chars, and encodes them as 4 base64 chars
    static void encodeTriple(char first, char second, char third,
                             std::string& output)
    {
        size_t keyIndex = 0;

        keyIndex = static_cast<size_t>(first & 0xFC) >> 2;
        output += key[keyIndex];

        keyIndex = static_cast<size_t>(first & 0x03) << 4;
        keyIndex += static_cast<size_t>(second & 0xF0) >> 4;
        output += key[keyIndex];

        keyIndex = static_cast<size_t>(second & 0x0F) << 2;
        keyIndex += static_cast<size_t>(third & 0xC0) >> 6;
        output += key[keyIndex];

        keyIndex = static_cast<size_t>(third & 0x3F);
        output += key[keyIndex];
    }

  public:
    // Accepts a partial string to encode, and writes the encoded characters to
    // the output stream. requires subsequently calling finalize to complete
    // stream.
    void encode(std::string_view data, std::string& output)
    {
        // Encode the last round of overflow chars first
        if (overflowCount == 2)
        {
            if (!data.empty())
            {
                encodeTriple(overflow1, overflow2, data[0], output);
                overflowCount = 0;
                data.remove_prefix(1);
            }
        }
        else if (overflowCount == 1)
        {
            if (data.size() >= 2)
            {
                encodeTriple(overflow1, data[0], data[1], output);
                overflowCount = 0;
                data.remove_prefix(2);
            }
        }

        while (data.size() >= 3)
        {
            encodeTriple(data[0], data[1], data[2], output);
            data.remove_prefix(3);
        }

        if (!data.empty() && overflowCount == 0)
        {
            overflow1 = data[0];
            overflowCount++;
            data.remove_prefix(1);
        }

        if (!data.empty() && overflowCount == 1)
        {
            overflow2 = data[0];
            overflowCount++;
            data.remove_prefix(1);
        }
    }

    // Completes a base64 output, by writing any MOD(3) characters to the
    // output, as well as any required trailing =
    void finalize(std::string& output)
    {
        if (overflowCount == 0)
        {
            return;
        }
        size_t keyIndex = static_cast<size_t>(overflow1 & 0xFC) >> 2;
        output += key[keyIndex];

        keyIndex = static_cast<size_t>(overflow1 & 0x03) << 4;
        if (overflowCount == 2)
        {
            keyIndex += static_cast<size_t>(overflow2 & 0xF0) >> 4;
            output += key[keyIndex];
            keyIndex = static_cast<size_t>(overflow2 & 0x0F) << 2;
            output += key[keyIndex];
        }
        else
        {
            output += key[keyIndex];
            output += '=';
        }
        output += '=';
        overflowCount = 0;
    }

    // Returns the required output buffer in characters for an input of size
    // inputSize
    static size_t constexpr encodedSize(size_t inputSize)
    {
        // Base64 encodes 3 character blocks as 4 character blocks
        // With a possibility of 2 trailing = characters
        return (inputSize + 2) / 3 * 4;
    }
};

inline std::string base64encode(std::string_view data)
{
    // Encodes a 3 character stream into a 4 character stream
    std::string out;
    Base64Encoder base64;
    out.reserve(Base64Encoder::encodedSize(data.size()));
    base64.encode(data, out);
    base64.finalize(out);
    return out;
}

// TODO this is temporary and should be deleted once base64 is refactored out of
// crow
inline bool base64Decode(std::string_view input, std::string& output)
{
    static const char nop = static_cast<char>(-1);
    // See note on encoding_data[] in above function
    static const std::array<char, 256> decodingData = {
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, 62,  nop, nop, nop, 63,  52,  53,  54,  55,  56,  57,  58,  59,
        60,  61,  nop, nop, nop, nop, nop, nop, nop, 0,   1,   2,   3,   4,
        5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,
        19,  20,  21,  22,  23,  24,  25,  nop, nop, nop, nop, nop, nop, 26,
        27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
        41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
        nop, nop, nop, nop};

    size_t inputLength = input.size();

    // allocate space for output string
    output.clear();
    output.reserve(((inputLength + 2) / 3) * 4);

    auto getCodeValue = [](char c) {
        auto code = static_cast<unsigned char>(c);
        // Ensure we cannot index outside the bounds of the decoding array
        static_assert(std::numeric_limits<decltype(code)>::max() <
                      decodingData.size());
        return decodingData[code];
    };

    // for each 4-bytes sequence from the input, extract 4 6-bits sequences by
    // dropping first two bits
    // and regenerate into 3 8-bits sequences

    for (size_t i = 0; i < inputLength; i++)
    {
        char base64code0 = 0;
        char base64code1 = 0;
        char base64code2 = 0; // initialized to 0 to suppress warnings

        base64code0 = getCodeValue(input[i]);
        if (base64code0 == nop)
        { // non base64 character
            return false;
        }
        if (!(++i < inputLength))
        { // we need at least two input bytes for first
          // byte output
            return false;
        }
        base64code1 = getCodeValue(input[i]);
        if (base64code1 == nop)
        { // non base64 character
            return false;
        }
        output +=
            static_cast<char>((base64code0 << 2) | ((base64code1 >> 4) & 0x3));

        if (++i < inputLength)
        {
            char c = input[i];
            if (c == '=')
            { // padding , end of input
                return (base64code1 & 0x0f) == 0;
            }
            base64code2 = getCodeValue(input[i]);
            if (base64code2 == nop)
            { // non base64 character
                return false;
            }
            output += static_cast<char>(((base64code1 << 4) & 0xf0) |
                                        ((base64code2 >> 2) & 0x0f));
        }

        if (++i < inputLength)
        {
            char c = input[i];
            if (c == '=')
            { // padding , end of input
                return (base64code2 & 0x03) == 0;
            }
            char base64code3 = getCodeValue(input[i]);
            if (base64code3 == nop)
            { // non base64 character
                return false;
            }
            output +=
                static_cast<char>((((base64code2 << 6) & 0xc0) | base64code3));
        }
    }

    return true;
}

inline bool constantTimeStringCompare(std::string_view a, std::string_view b)
{
    // Important note, this function is ONLY constant time if the two input
    // sizes are the same
    if (a.size() != b.size())
    {
        return false;
    }
    return CRYPTO_memcmp(a.data(), b.data(), a.size()) == 0;
}

struct ConstantTimeCompare
{
    bool operator()(std::string_view a, std::string_view b) const
    {
        return constantTimeStringCompare(a, b);
    }
};

namespace details
{
inline boost::urls::url
    appendUrlPieces(boost::urls::url& url,
                    const std::initializer_list<std::string_view> args)
{
    for (std::string_view arg : args)
    {
        url.segments().push_back(arg);
    }
    return url;
}

} // namespace details

class OrMorePaths
{};

template <typename... AV>
inline void appendUrlPieces(boost::urls::url& url, const AV... args)
{
    details::appendUrlPieces(url, {args...});
}

namespace details
{

// std::reference_wrapper<std::string> - extracts segment to variable
//                    std::string_view - checks if segment is equal to variable
using UrlSegment = std::variant<std::reference_wrapper<std::string>,
                                std::string_view, OrMorePaths>;

enum class UrlParseResult
{
    Continue,
    Fail,
    Done,
};

class UrlSegmentMatcherVisitor
{
  public:
    UrlParseResult operator()(std::string& output)
    {
        output = segment;
        return UrlParseResult::Continue;
    }

    UrlParseResult operator()(std::string_view expected)
    {
        if (segment == expected)
        {
            return UrlParseResult::Continue;
        }
        return UrlParseResult::Fail;
    }

    UrlParseResult operator()(OrMorePaths /*unused*/)
    {
        return UrlParseResult::Done;
    }

    explicit UrlSegmentMatcherVisitor(std::string_view segmentIn) :
        segment(segmentIn)
    {}

  private:
    std::string_view segment;
};

inline bool readUrlSegments(const boost::urls::url_view_base& url,
                            std::initializer_list<UrlSegment> segments)
{
    const boost::urls::segments_view& urlSegments = url.segments();

    if (!urlSegments.is_absolute())
    {
        return false;
    }

    boost::urls::segments_view::const_iterator it = urlSegments.begin();
    boost::urls::segments_view::const_iterator end = urlSegments.end();

    for (const auto& segment : segments)
    {
        if (it == end)
        {
            // If the request ends with an "any" path, this was successful
            return std::holds_alternative<OrMorePaths>(segment);
        }
        UrlParseResult res = std::visit(UrlSegmentMatcherVisitor(*it), segment);
        if (res == UrlParseResult::Done)
        {
            return true;
        }
        if (res == UrlParseResult::Fail)
        {
            return false;
        }
        it++;
    }

    // There will be an empty segment at the end if the URI ends with a "/"
    // e.g. /redfish/v1/Chassis/
    if ((it != end) && urlSegments.back().empty())
    {
        it++;
    }
    return it == end;
}

} // namespace details

template <typename... Args>
inline bool readUrlSegments(const boost::urls::url_view_base& url,
                            Args&&... args)
{
    return details::readUrlSegments(url, {std::forward<Args>(args)...});
}

inline boost::urls::url
    replaceUrlSegment(const boost::urls::url_view_base& urlView,
                      const uint replaceLoc, std::string_view newSegment)
{
    const boost::urls::segments_view& urlSegments = urlView.segments();
    boost::urls::url url("/");

    if (!urlSegments.is_absolute())
    {
        return url;
    }

    boost::urls::segments_view::iterator it = urlSegments.begin();
    boost::urls::segments_view::iterator end = urlSegments.end();

    for (uint idx = 0; it != end; it++, idx++)
    {
        if (idx == replaceLoc)
        {
            url.segments().push_back(newSegment);
        }
        else
        {
            url.segments().push_back(*it);
        }
    }

    return url;
}

inline void setProtocolDefaults(boost::urls::url& url,
                                std::string_view protocol)
{
    if (url.has_scheme())
    {
        return;
    }
    if (protocol == "Redfish" || protocol.empty())
    {
        if (url.port_number() == 443)
        {
            url.set_scheme("https");
        }
        if (url.port_number() == 80)
        {
            if constexpr (BMCWEB_INSECURE_PUSH_STYLE_NOTIFICATION)
            {
                url.set_scheme("http");
            }
        }
    }
    else if (protocol == "SNMPv2c")
    {
        url.set_scheme("snmp");
    }
}

inline void setPortDefaults(boost::urls::url& url)
{
    uint16_t port = url.port_number();
    if (port != 0)
    {
        return;
    }

    // If the user hasn't explicitly stated a port, pick one explicitly for them
    // based on the protocol defaults
    if (url.scheme() == "http")
    {
        url.set_port_number(80);
    }
    if (url.scheme() == "https")
    {
        url.set_port_number(443);
    }
    if (url.scheme() == "snmp")
    {
        url.set_port_number(162);
    }
}

} // namespace utility
} // namespace crow

namespace nlohmann
{
template <std::derived_from<boost::urls::url_view_base> URL>
struct adl_serializer<URL>
{
    // NOLINTNEXTLINE(readability-identifier-naming)
    static void to_json(json& j, const URL& url)
    {
        j = url.buffer();
    }
};
} // namespace nlohmann
