/*
 * Copyright (C) 2002, 2003 The Karbon Developers
 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
 * Copyright (C) 2007-2018 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "SVGParserUtilities.h"

#include "Document.h"
#include "FloatRect.h"
#include <limits>
#include <wtf/ASCIICType.h>
#include <wtf/text/StringParsingBuffer.h>
#include <wtf/text/StringView.h>

namespace WebCore {

template <typename FloatType> static inline bool isValidRange(const FloatType& x)
{
    static const FloatType max = std::numeric_limits<FloatType>::max();
    return x >= -max && x <= max;
}

// We use this generic parseNumber function to allow the Path parsing code to work 
// at a higher precision internally, without any unnecessary runtime cost or code
// complexity.
// FIXME: Can this be shared/replaced with number parsing in WTF?
template <typename CharacterType, typename FloatType = float> static Optional<FloatType> genericParseNumber(StringParsingBuffer<CharacterType>& buffer, SuffixSkippingPolicy skip = SuffixSkippingPolicy::Skip)
{
    FloatType number = 0;
    FloatType integer = 0;
    FloatType decimal = 0;
    FloatType frac = 1;
    FloatType exponent = 0;
    int sign = 1;
    int expsign = 1;
    auto start = buffer.position();

    // read the sign
    if (buffer.hasCharactersRemaining() && *buffer == '+')
        ++buffer;
    else if (buffer.hasCharactersRemaining() && *buffer == '-') {
        ++buffer;
        sign = -1;
    } 
    
    if (buffer.atEnd() || (!isASCIIDigit(*buffer) && *buffer != '.'))
        return WTF::nullopt;

    // read the integer part, build right-to-left
    auto ptrStartIntPart = buffer.position();
    
    // Advance to first non-digit.
    skipWhile<CharacterType, isASCIIDigit>(buffer);

    if (buffer.position() != ptrStartIntPart) {
        auto ptrScanIntPart = buffer.position() - 1;
        FloatType multiplier = 1;
        while (ptrScanIntPart >= ptrStartIntPart) {
            integer += multiplier * static_cast<FloatType>(*(ptrScanIntPart--) - '0');
            multiplier *= 10;
        }
        // Bail out early if this overflows.
        if (!isValidRange(integer))
            return WTF::nullopt;
    }

    // read the decimals
    if (buffer.hasCharactersRemaining() && *buffer == '.') {
        ++buffer;
        
        // There must be a least one digit following the .
        if (buffer.atEnd() || !isASCIIDigit(*buffer))
            return WTF::nullopt;
        
        while (buffer.hasCharactersRemaining() && isASCIIDigit(*buffer))
            decimal += (*(buffer++) - '0') * (frac *= static_cast<FloatType>(0.1));
    }

    // read the exponent part
    if (buffer.position() != start && buffer.position() + 1 < buffer.end() && (*buffer == 'e' || *buffer == 'E')
        && (buffer[1] != 'x' && buffer[1] != 'm')) {
        ++buffer;

        // read the sign of the exponent
        if (*buffer == '+')
            ++buffer;
        else if (*buffer == '-') {
            ++buffer;
            expsign = -1;
        }
        
        // There must be an exponent
        if (buffer.atEnd() || !isASCIIDigit(*buffer))
            return WTF::nullopt;

        while (buffer.hasCharactersRemaining() && isASCIIDigit(*buffer)) {
            exponent *= static_cast<FloatType>(10);
            exponent += *buffer++ - '0';
        }
        // Make sure exponent is valid.
        if (!isValidRange(exponent) || exponent > std::numeric_limits<FloatType>::max_exponent)
            return WTF::nullopt;
    }

    number = integer + decimal;
    number *= sign;

    if (exponent)
        number *= static_cast<FloatType>(pow(10.0, expsign * static_cast<int>(exponent)));

    // Don't return Infinity() or NaN().
    if (!isValidRange(number))
        return WTF::nullopt;

    if (start == buffer.position())
        return WTF::nullopt;

    if (skip == SuffixSkippingPolicy::Skip)
        skipOptionalSVGSpacesOrDelimiter(buffer);

    return number;
}

Optional<float> parseNumber(StringParsingBuffer<LChar>& buffer, SuffixSkippingPolicy skip)
{
    return genericParseNumber(buffer, skip);
}

Optional<float> parseNumber(StringParsingBuffer<UChar>& buffer, SuffixSkippingPolicy skip)
{
    return genericParseNumber(buffer, skip);
}

Optional<float> parseNumber(const StringView& string, SuffixSkippingPolicy skip)
{
    return readCharactersForParsing(string, [skip](auto buffer) -> Optional<float> {
        auto result = genericParseNumber(buffer, skip);
        if (!buffer.atEnd())
            return WTF::nullopt;
        return result;
    });
}

// only used to parse largeArcFlag and sweepFlag which must be a "0" or "1"
// and might not have any whitespace/comma after it
template <typename CharacterType> Optional<bool> genericParseArcFlag(StringParsingBuffer<CharacterType>& buffer)
{
    if (buffer.atEnd())
        return WTF::nullopt;

    const CharacterType flagChar = *buffer;
    ++buffer;

    bool flag;
    if (flagChar == '0')
        flag = false;
    else if (flagChar == '1')
        flag = true;
    else
        return WTF::nullopt;

    skipOptionalSVGSpacesOrDelimiter(buffer);
    
    return flag;
}

Optional<bool> parseArcFlag(StringParsingBuffer<LChar>& buffer)
{
    return genericParseArcFlag(buffer);
}

Optional<bool> parseArcFlag(StringParsingBuffer<UChar>& buffer)
{
    return genericParseArcFlag(buffer);
}

Optional<std::pair<float, float>> parseNumberOptionalNumber(const StringView& string)
{
    if (string.isEmpty())
        return WTF::nullopt;

    return readCharactersForParsing(string, [](auto buffer) -> Optional<std::pair<float, float>> {
        auto x = parseNumber(buffer);
        if (!x)
            return WTF::nullopt;

        if (buffer.atEnd())
            return std::make_pair(*x, *x);

        auto y = parseNumber(buffer, SuffixSkippingPolicy::DontSkip);
        if (!y)
            return WTF::nullopt;

        if (!buffer.atEnd())
            return WTF::nullopt;

        return std::make_pair(*x, *y);
    });
}

Optional<FloatPoint> parsePoint(const StringView& string)
{
    if (string.isEmpty())
        return WTF::nullopt;

    return readCharactersForParsing(string, [](auto buffer) -> Optional<FloatPoint> {
        if (!skipOptionalSVGSpaces(buffer))
            return WTF::nullopt;

        auto point = parseFloatPoint(buffer);
        if (!point)
            return WTF::nullopt;

        // Disallow anything except spaces at the end.
        skipOptionalSVGSpaces(buffer);
        
        return point;
    });
}

Optional<FloatRect> parseRect(const StringView& string)
{
    return readCharactersForParsing(string, [](auto buffer) -> Optional<FloatRect> {
        skipOptionalSVGSpaces(buffer);
        
        auto x = parseNumber(buffer);
        if (!x)
            return WTF::nullopt;
        auto y = parseNumber(buffer);
        if (!y)
            return WTF::nullopt;
        auto width = parseNumber(buffer);
        if (!width)
            return WTF::nullopt;
        auto height = parseNumber(buffer, SuffixSkippingPolicy::DontSkip);
        if (!height)
            return WTF::nullopt;

        return FloatRect { *x, *y, *width, *height };
    });
}

Optional<HashSet<String>> parseGlyphName(const StringView& string)
{
    // FIXME: Parsing error detection is missing.

    return readCharactersForParsing(string, [](auto buffer) -> HashSet<String> {
        skipOptionalSVGSpaces(buffer);

        HashSet<String> values;

        while (buffer.hasCharactersRemaining()) {
            // Leading and trailing white space, and white space before and after separators, will be ignored.
            auto inputStart = buffer.position();

            skipUntil(buffer, ',');

            if (buffer.position() == inputStart)
                break;

            // walk backwards from the ; to ignore any whitespace
            auto inputEnd = buffer.position() - 1;
            while (inputStart < inputEnd && isSVGSpace(*inputEnd))
                --inputEnd;

            values.add(String(inputStart, inputEnd - inputStart + 1));
            skipOptionalSVGSpacesOrDelimiter(buffer, ',');
        }
        return values;
    });

}

template<typename CharacterType> static Optional<UnicodeRange> parseUnicodeRange(StringParsingBuffer<CharacterType> buffer)
{
    unsigned length = buffer.lengthRemaining();
    if (length < 2 || buffer[0] != 'U' || buffer[1] != '+')
        return WTF::nullopt;

    buffer += 2;

    // Parse the starting hex number (or its prefix).
    unsigned startRange = 0;
    unsigned startLength = 0;

    while (buffer.hasCharactersRemaining()) {
        if (!isASCIIHexDigit(*buffer))
            break;
        ++startLength;
        if (startLength > 6)
            return WTF::nullopt;
        startRange = (startRange << 4) | toASCIIHexValue(*buffer);
        ++buffer;
    }

    // Handle the case of ranges separated by "-" sign.
    if (2 + startLength < length && *buffer == '-') {
        if (!startLength)
            return WTF::nullopt;
        
        // Parse the ending hex number (or its prefix).
        unsigned endRange = 0;
        unsigned endLength = 0;
        ++buffer;
        while (buffer.hasCharactersRemaining()) {
            if (!isASCIIHexDigit(*buffer))
                break;
            ++endLength;
            if (endLength > 6)
                return WTF::nullopt;
            endRange = (endRange << 4) | toASCIIHexValue(*buffer);
            ++buffer;
        }
        
        if (!endLength)
            return WTF::nullopt;
        
        UnicodeRange range;
        range.first = startRange;
        range.second = endRange;
        return range;
    }
    
    // Handle the case of a number with some optional trailing question marks.
    unsigned endRange = startRange;
    while (buffer.hasCharactersRemaining()) {
        if (*buffer != '?')
            break;
        ++startLength;
        if (startLength > 6)
            return WTF::nullopt;
        startRange <<= 4;
        endRange = (endRange << 4) | 0xF;
        ++buffer;
    }
    
    if (!startLength)
        return WTF::nullopt;
    
    UnicodeRange range;
    range.first = startRange;
    range.second = endRange;
    return range;
}

Optional<std::pair<UnicodeRanges, HashSet<String>>> parseKerningUnicodeString(const StringView& string)
{
    // FIXME: Parsing error detection is missing.

    return readCharactersForParsing(string, [](auto buffer) -> std::pair<UnicodeRanges, HashSet<String>> {
        UnicodeRanges rangeList;
        HashSet<String> stringList;

        while (1) {
            auto inputStart = buffer.position();

            skipUntil(buffer, ',');

            if (buffer.position() == inputStart)
                break;

            // Try to parse unicode range first
            if (auto range = parseUnicodeRange(StringParsingBuffer { inputStart, buffer.position() }))
                rangeList.append(WTFMove(*range));
            else
                stringList.add(String(inputStart, buffer.position() - inputStart));

            if (buffer.atEnd())
                break;

            ++buffer;
        }

        return std::make_pair(WTFMove(rangeList), WTFMove(stringList));
    });
}

template <typename CharacterType> static Optional<FloatPoint> genericParseFloatPoint(StringParsingBuffer<CharacterType>& buffer)
{
    auto x = parseNumber(buffer);
    if (!x)
        return WTF::nullopt;

    auto y = parseNumber(buffer);
    if (!y)
        return WTF::nullopt;

    return FloatPoint { *x, *y };
}

Optional<FloatPoint> parseFloatPoint(StringParsingBuffer<LChar>& buffer)
{
    return genericParseFloatPoint(buffer);
}

Optional<FloatPoint> parseFloatPoint(StringParsingBuffer<UChar>& buffer)
{
    return genericParseFloatPoint(buffer);
}

}
