/*
 * Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
 * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
 * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#pragma once

#include <wtf/Forward.h>
#include <wtf/OptionSet.h>
#include <wtf/Span.h>
#include <wtf/text/StringConcatenate.h>
#include <wtf/text/WTFString.h>

namespace WTF {

enum class Base64EncodePolicy {
    DoNotInsertLFs,
    InsertLFs,
    URL // No padding, no LFs.
};

enum class Base64EncodeMap { Default, URL };

enum class Base64DecodeOptions : uint8_t {
    ValidatePadding         = 1 << 0,
    IgnoreSpacesAndNewLines = 1 << 1,
    DiscardVerticalTab      = 1 << 2,
};

enum class Base64DecodeMap { Default, URL };

struct Base64Specification {
    Span<const std::byte> input;
    Base64EncodePolicy policy;
    Base64EncodeMap map;
};

static constexpr unsigned maximumBase64LineLengthWhenInsertingLFs = 76;

// If the input string is pathologically large, just return nothing.
// Rather than being perfectly precise, this is a bit conservative.
static constexpr unsigned maximumBase64EncoderInputBufferSize = std::numeric_limits<unsigned>::max() / 77 * 76 / 4 * 3 - 2;

unsigned calculateBase64EncodedSize(unsigned inputLength, Base64EncodePolicy);

template<typename CharacterType> bool isBase64OrBase64URLCharacter(CharacterType);

WTF_EXPORT_PRIVATE void base64Encode(Span<const std::byte>, Span<UChar>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
WTF_EXPORT_PRIVATE void base64Encode(Span<const std::byte>, Span<LChar>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);

WTF_EXPORT_PRIVATE Vector<uint8_t> base64EncodeToVector(Span<const std::byte>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
Vector<uint8_t> base64EncodeToVector(Span<const uint8_t>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
Vector<uint8_t> base64EncodeToVector(Span<const char>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
Vector<uint8_t> base64EncodeToVector(const CString&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
Vector<uint8_t> base64EncodeToVector(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);

WTF_EXPORT_PRIVATE String base64EncodeToString(Span<const std::byte>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
String base64EncodeToString(Span<const uint8_t>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
String base64EncodeToString(Span<const char>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
String base64EncodeToString(const CString&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
String base64EncodeToString(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);

WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(Span<const std::byte>, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
WTF_EXPORT_PRIVATE std::optional<Vector<uint8_t>> base64Decode(StringView, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
std::optional<Vector<uint8_t>> base64Decode(Span<const uint8_t>, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
std::optional<Vector<uint8_t>> base64Decode(Span<const char>, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
std::optional<Vector<uint8_t>> base64Decode(const String&, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);
std::optional<Vector<uint8_t>> base64Decode(const void*, unsigned, OptionSet<Base64DecodeOptions> = { }, Base64DecodeMap = Base64DecodeMap::Default);

// All the same functions modified for base64url, as defined in RFC 4648.
// This format uses '-' and '_' instead of '+' and '/' respectively.

Vector<uint8_t> base64URLEncodeToVector(Span<const std::byte>);
Vector<uint8_t> base64URLEncodeToVector(Span<const uint8_t>);
Vector<uint8_t> base64URLEncodeToVector(Span<const char>);
Vector<uint8_t> base64URLEncodeToVector(const CString&);
Vector<uint8_t> base64URLEncodeToVector(const void*, unsigned);

String base64URLEncodeToString(Span<const std::byte>);
String base64URLEncodeToString(Span<const uint8_t>);
String base64URLEncodeToString(Span<const char>);
String base64URLEncodeToString(const CString&);
String base64URLEncodeToString(const void*, unsigned);

std::optional<Vector<uint8_t>> base64URLDecode(StringView);
inline std::optional<Vector<uint8_t>> base64URLDecode(ASCIILiteral literal) { return base64URLDecode(StringView { literal }); }
std::optional<Vector<uint8_t>> base64URLDecode(const String&);
std::optional<Vector<uint8_t>> base64URLDecode(Span<const std::byte>);
std::optional<Vector<uint8_t>> base64URLDecode(Span<const uint8_t>);
std::optional<Vector<uint8_t>> base64URLDecode(Span<const char>);
std::optional<Vector<uint8_t>> base64URLDecode(const void*, unsigned);

// Versions for use with StringBuilder / makeString.

Base64Specification base64Encoded(Span<const std::byte>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
Base64Specification base64Encoded(Span<const uint8_t>, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
Base64Specification base64Encoded(const CString&, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);
Base64Specification base64Encoded(const void*, unsigned, Base64EncodePolicy = Base64EncodePolicy::DoNotInsertLFs, Base64EncodeMap = Base64EncodeMap::Default);

Base64Specification base64URLEncoded(Span<const std::byte>);
Base64Specification base64URLEncoded(Span<const uint8_t>);
Base64Specification base64URLEncoded(const CString&);
Base64Specification base64URLEncoded(const void*, unsigned);


inline Vector<uint8_t> base64EncodeToVector(Span<const uint8_t> input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToVector(asBytes(input), policy, map);
}

inline Vector<uint8_t> base64EncodeToVector(Span<const char> input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToVector(asBytes(input), policy, map);
}

inline Vector<uint8_t> base64EncodeToVector(const CString& input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToVector(input.bytes(), policy, map);
}

inline Vector<uint8_t> base64EncodeToVector(const void* input, unsigned length, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToVector({ static_cast<const std::byte*>(input), length }, policy, map);
}

inline String base64EncodeToString(Span<const uint8_t> input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToString(asBytes(input), policy, map);
}

inline String base64EncodeToString(Span<const char> input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToString(asBytes(input), policy, map);
}

inline String base64EncodeToString(const CString& input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToString(input.bytes(), policy, map);
}

inline String base64EncodeToString(const void* input, unsigned length, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64EncodeToString({ static_cast<const std::byte*>(input), length }, policy, map);
}

inline std::optional<Vector<uint8_t>> base64Decode(Span<const uint8_t> input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
{
    return base64Decode(asBytes(input), options, map);
}

inline std::optional<Vector<uint8_t>> base64Decode(Span<const char> input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
{
    return base64Decode(asBytes(input), options, map);
}

inline std::optional<Vector<uint8_t>> base64Decode(const String& input, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
{
    return base64Decode(StringView { input }, options, map);
}

inline std::optional<Vector<uint8_t>> base64Decode(const void* input, unsigned length, OptionSet<Base64DecodeOptions> options, Base64DecodeMap map)
{
    return base64Decode({ static_cast<const std::byte*>(input), length }, options, map);
}

inline Vector<uint8_t> base64URLEncodeToVector(Span<const std::byte> input)
{
    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline Vector<uint8_t> base64URLEncodeToVector(Span<const uint8_t> input)
{
    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline Vector<uint8_t> base64URLEncodeToVector(Span<const char> input)
{
    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline Vector<uint8_t> base64URLEncodeToVector(const CString& input)
{
    return base64EncodeToVector(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline Vector<uint8_t> base64URLEncodeToVector(const void* input, unsigned length)
{
    return base64EncodeToVector(input, length, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline String base64URLEncodeToString(Span<const std::byte> input)
{
    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline String base64URLEncodeToString(Span<const uint8_t> input)
{
    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline String base64URLEncodeToString(Span<const char> input)
{
    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline String base64URLEncodeToString(const CString& input)
{
    return base64EncodeToString(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline String base64URLEncodeToString(const void* input, unsigned length)
{
    return base64EncodeToString(input, length, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline std::optional<Vector<uint8_t>> base64URLDecode(StringView input)
{
    return base64Decode(input, { }, Base64DecodeMap::URL);
}

inline std::optional<Vector<uint8_t>> base64URLDecode(const String& input)
{
    return base64Decode(input, { }, Base64DecodeMap::URL);
}

inline std::optional<Vector<uint8_t>> base64URLDecode(Span<const std::byte> input)
{
    return base64Decode(input, { }, Base64DecodeMap::URL);
}

inline std::optional<Vector<uint8_t>> base64URLDecode(Span<const uint8_t> input)
{
    return base64Decode(input, { }, Base64DecodeMap::URL);
}

inline std::optional<Vector<uint8_t>> base64URLDecode(Span<const char> input)
{
    return base64Decode(input, { }, Base64DecodeMap::URL);
}

inline std::optional<Vector<uint8_t>> base64URLDecode(const void* input, unsigned length)
{
    return base64Decode(input, length, { }, Base64DecodeMap::URL);
}

template<typename CharacterType> bool isBase64OrBase64URLCharacter(CharacterType c)
{
    return isASCIIAlphanumeric(c) || c == '+' || c == '/' || c == '-' || c == '_';
}

inline unsigned calculateBase64EncodedSize(unsigned inputLength, Base64EncodePolicy policy)
{
    if (!inputLength)
        return 0;

    if (inputLength > maximumBase64EncoderInputBufferSize)
        return 0;

    auto basePaddedEncodedSize = [&] {
        return ((inputLength + 2) / 3) * 4;
    };

    auto baseUnpaddedEncodedSize = [&] {
        return ((inputLength * 4) + 2) / 3;
    };

    switch (policy) {
    case Base64EncodePolicy::DoNotInsertLFs:
        return basePaddedEncodedSize();

    case Base64EncodePolicy::InsertLFs: {
        auto result = basePaddedEncodedSize();
        return result + ((result - 1) / maximumBase64LineLengthWhenInsertingLFs);
    }

    case Base64EncodePolicy::URL:
        return baseUnpaddedEncodedSize();
    }

    ASSERT_NOT_REACHED();
    return 0;
}

inline Base64Specification base64Encoded(Span<const std::byte> input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return { input, policy, map };
}

inline Base64Specification base64Encoded(Span<const uint8_t> input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64Encoded(asBytes(input), policy, map);
}

inline Base64Specification base64Encoded(const CString& input, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64Encoded(input.bytes(), policy, map);
}

inline Base64Specification base64Encoded(const void* input, unsigned length, Base64EncodePolicy policy, Base64EncodeMap map)
{
    return base64Encoded({ static_cast<const std::byte*>(input), length }, policy, map);
}

inline Base64Specification base64URLEncoded(Span<const std::byte> input)
{
    return base64Encoded(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline Base64Specification base64URLEncoded(Span<const uint8_t> input)
{
    return base64Encoded(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline Base64Specification base64URLEncoded(const CString& input)
{
    return base64Encoded(input, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

inline Base64Specification base64URLEncoded(const void* input, unsigned length)
{
    return base64Encoded(input, length, Base64EncodePolicy::URL, Base64EncodeMap::URL);
}

template<> class StringTypeAdapter<Base64Specification> {
public:
    StringTypeAdapter(const Base64Specification& base64)
        : m_base64 { base64 }
        , m_encodedLength { calculateBase64EncodedSize(base64.input.size(), base64.policy) }
    {
    }

    unsigned length() const { return m_encodedLength; }
    bool is8Bit() const { return true; }

    template<typename CharacterType> void writeTo(CharacterType* destination) const
    {
        base64Encode(m_base64.input, Span { destination, m_encodedLength }, m_base64.policy, m_base64.map);
    }

private:
    Base64Specification m_base64;
    unsigned m_encodedLength;
};

} // namespace WTF

using WTF::Base64DecodeOptions;
using WTF::Base64EncodePolicy;
using WTF::base64Decode;
using WTF::base64EncodeToString;
using WTF::base64EncodeToVector;
using WTF::base64Encoded;
using WTF::base64URLDecode;
using WTF::base64URLDecode;
using WTF::base64URLEncodeToString;
using WTF::base64URLEncodeToVector;
using WTF::base64URLEncoded;
using WTF::isBase64OrBase64URLCharacter;
