/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller ( mueller@kde.org )
 * Copyright (C) 2003-2021 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
 *
 * 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 "Length.h"

#include "AnimationUtilities.h"
#include "CalcExpressionBlendLength.h"
#include "CalcExpressionLength.h"
#include "CalcExpressionOperation.h"
#include "CalculationValue.h"
#include <wtf/ASCIICType.h>
#include <wtf/HashMap.h>
#include <wtf/MallocPtr.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringToIntegerConversion.h>
#include <wtf/text/StringView.h>
#include <wtf/text/TextStream.h>

namespace WebCore {

static Length parseLength(const UChar* data, unsigned length)
{
    if (length == 0)
        return Length(1, LengthType::Relative);

    unsigned i = 0;
    while (i < length && isSpaceOrNewline(data[i]))
        ++i;
    if (i < length && (data[i] == '+' || data[i] == '-'))
        ++i;
    while (i < length && isASCIIDigit(data[i]))
        ++i;
    unsigned intLength = i;
    while (i < length && (isASCIIDigit(data[i]) || data[i] == '.'))
        ++i;
    unsigned doubleLength = i;

    // IE quirk: Skip whitespace between the number and the % character (20 % => 20%).
    while (i < length && isSpaceOrNewline(data[i]))
        ++i;

    bool ok;
    UChar next = (i < length) ? data[i] : ' ';
    if (next == '%') {
        // IE quirk: accept decimal fractions for percentages.
        double r = charactersToDouble(data, doubleLength, &ok);
        if (ok)
            return Length(r, LengthType::Percent);
        return Length(1, LengthType::Relative);
    }
    auto r = parseInteger<int>({ data, intLength });
    if (next == '*')
        return Length(r.value_or(1), LengthType::Relative);
    if (r)
        return Length(*r, LengthType::Fixed);
    return Length(0, LengthType::Relative);
}

static unsigned countCharacter(StringImpl& string, UChar character)
{
    unsigned count = 0;
    unsigned length = string.length();
    for (unsigned i = 0; i < length; ++i)
        count += string[i] == character;
    return count;
}

UniqueArray<Length> newCoordsArray(const String& string, int& len)
{
    unsigned length = string.length();
    LChar* spacifiedCharacters;
    auto str = StringImpl::createUninitialized(length, spacifiedCharacters);
    for (unsigned i = 0; i < length; i++) {
        UChar cc = string[i];
        if (cc > '9' || (cc < '0' && cc != '-' && cc != '*' && cc != '.'))
            spacifiedCharacters[i] = ' ';
        else
            spacifiedCharacters[i] = cc;
    }
    str = str->simplifyWhiteSpace();

    len = countCharacter(str, ' ') + 1;
    auto r = makeUniqueArray<Length>(len);

    int i = 0;
    unsigned pos = 0;
    size_t pos2;

    while ((pos2 = str->find(' ', pos)) != notFound) {
        r[i++] = parseLength(str->characters16() + pos, pos2 - pos);
        pos = pos2+1;
    }
    r[i] = parseLength(str->characters16() + pos, str->length() - pos);

    ASSERT(i == len - 1);

    return r;
}

UniqueArray<Length> newLengthArray(const String& string, int& len)
{
    RefPtr<StringImpl> str = string.impl()->simplifyWhiteSpace();
    if (!str->length()) {
        len = 1;
        return nullptr;
    }

    len = countCharacter(*str, ',') + 1;
    auto r = makeUniqueArray<Length>(len);

    int i = 0;
    unsigned pos = 0;
    size_t pos2;

    auto upconvertedCharacters = StringView(str.get()).upconvertedCharacters();
    while ((pos2 = str->find(',', pos)) != notFound) {
        r[i++] = parseLength(upconvertedCharacters + pos, pos2 - pos);
        pos = pos2+1;
    }

    ASSERT(i == len - 1);

    // IE Quirk: If the last comma is the last char skip it and reduce len by one.
    if (str->length()-pos > 0)
        r[i] = parseLength(upconvertedCharacters + pos, str->length() - pos);
    else
        len--;

    return r;
}

class CalculationValueMap {
public:
    CalculationValueMap();

    unsigned insert(Ref<CalculationValue>&&);
    void ref(unsigned handle);
    void deref(unsigned handle);

    CalculationValue& get(unsigned handle) const;

private:
    struct Entry {
        uint64_t referenceCountMinusOne;
        CalculationValue* value;
        Entry();
        Entry(CalculationValue&);
    };

    unsigned m_nextAvailableHandle;
    HashMap<unsigned, Entry> m_map;
};

inline CalculationValueMap::Entry::Entry()
    : referenceCountMinusOne(0)
    , value(nullptr)
{
}

inline CalculationValueMap::Entry::Entry(CalculationValue& value)
    : referenceCountMinusOne(0)
    , value(&value)
{
}

inline CalculationValueMap::CalculationValueMap()
    : m_nextAvailableHandle(1)
{
}
    
inline unsigned CalculationValueMap::insert(Ref<CalculationValue>&& value)
{
    ASSERT(m_nextAvailableHandle);

    // The leakRef below is balanced by the adoptRef in the deref member function.
    Entry leakedValue = value.leakRef();

    // FIXME: This monotonically increasing handle generation scheme is potentially wasteful
    // of the handle space. Consider reusing empty handles. https://bugs.webkit.org/show_bug.cgi?id=80489
    while (!m_map.isValidKey(m_nextAvailableHandle) || !m_map.add(m_nextAvailableHandle, leakedValue).isNewEntry)
        ++m_nextAvailableHandle;

    return m_nextAvailableHandle++;
}

inline CalculationValue& CalculationValueMap::get(unsigned handle) const
{
    ASSERT(m_map.contains(handle));

    return *m_map.find(handle)->value.value;
}

inline void CalculationValueMap::ref(unsigned handle)
{
    ASSERT(m_map.contains(handle));

    ++m_map.find(handle)->value.referenceCountMinusOne;
}

inline void CalculationValueMap::deref(unsigned handle)
{
    ASSERT(m_map.contains(handle));

    auto it = m_map.find(handle);
    if (it->value.referenceCountMinusOne) {
        --it->value.referenceCountMinusOne;
        return;
    }

    // The adoptRef here is balanced by the leakRef in the insert member function.
    Ref<CalculationValue> value { adoptRef(*it->value.value) };

    m_map.remove(it);
}

static CalculationValueMap& calculationValues()
{
    static NeverDestroyed<CalculationValueMap> map;
    return map;
}

Length::Length(Ref<CalculationValue>&& value)
    : m_type(LengthType::Calculated)
{
    m_calculationValueHandle = calculationValues().insert(WTFMove(value));
}

CalculationValue& Length::calculationValue() const
{
    ASSERT(isCalculated());
    return calculationValues().get(m_calculationValueHandle);
}
    
void Length::ref() const
{
    ASSERT(isCalculated());
    calculationValues().ref(m_calculationValueHandle);
}

void Length::deref() const
{
    ASSERT(isCalculated());
    calculationValues().deref(m_calculationValueHandle);
}

float Length::nonNanCalculatedValue(float maxValue) const
{
    ASSERT(isCalculated());
    float result = calculationValue().evaluate(maxValue);
    if (std::isnan(result))
        return 0;
    return result;
}

bool Length::isCalculatedEqual(const Length& other) const
{
    return calculationValue() == other.calculationValue();
}

Length convertTo100PercentMinusLength(const Length& length)
{
    if (length.isPercent())
        return Length(100 - length.value(), LengthType::Percent);
    
    // Turn this into a calc expression: calc(100% - length)
    Vector<std::unique_ptr<CalcExpressionNode>> lengths;
    lengths.reserveInitialCapacity(2);
    lengths.uncheckedAppend(makeUnique<CalcExpressionLength>(Length(100, LengthType::Percent)));
    lengths.uncheckedAppend(makeUnique<CalcExpressionLength>(length));
    auto op = makeUnique<CalcExpressionOperation>(WTFMove(lengths), CalcOperator::Subtract);
    return Length(CalculationValue::create(WTFMove(op), ValueRange::All));
}

static Length blendMixedTypes(const Length& from, const Length& to, const BlendingContext& context)
{
    if (!to.isCalculated() && !from.isPercent() && (context.progress == 1 || from.isZero()))
        return blend(Length(0, to.type()), to, context);

    if (!from.isCalculated() && !to.isPercent() && (!context.progress || to.isZero()))
        return blend(from, Length(0, from.type()), context);

    if (from.isIntrinsicOrAuto() || to.isIntrinsicOrAuto() || from.isRelative() || to.isRelative())
        return { 0, LengthType::Fixed };

    auto blend = makeUnique<CalcExpressionBlendLength>(from, to, context.progress);
    return Length(CalculationValue::create(WTFMove(blend), ValueRange::All));
}

Length blend(const Length& from, const Length& to, const BlendingContext& context)
{
    if ((from.isAuto() || to.isAuto()) || (from.isUndefined() || to.isUndefined()))
        return context.progress < 0.5 ? from : to;

    if (from.isCalculated() || to.isCalculated() || (from.type() != to.type()))
        return blendMixedTypes(from, to, context);

    if (!context.progress)
        return from;

    if (context.progress == 1)
        return to;

    LengthType resultType = to.type();
    if (to.isZero())
        resultType = from.type();

    if (resultType == LengthType::Percent) {
        float fromPercent = from.isZero() ? 0 : from.percent();
        float toPercent = to.isZero() ? 0 : to.percent();
        return Length(WebCore::blend(fromPercent, toPercent, context), LengthType::Percent);
    }

    float fromValue = from.isZero() ? 0 : from.value();
    float toValue = to.isZero() ? 0 : to.value();
    return Length(WebCore::blend(fromValue, toValue, context), resultType);
}

Length blend(const Length& from, const Length& to, const BlendingContext& context, ValueRange valueRange)
{
    auto blended = blend(from, to, context);
    if (valueRange == ValueRange::NonNegative && blended.isNegative()) {
        auto type = from.isZero() ? to.type() : from.type();
        if (type != LengthType::Calculated)
            return { 0, type };
        return { 0, LengthType::Fixed };
    }
    return blended;
}

struct SameSizeAsLength {
    int32_t value;
    int32_t metaData;
};
COMPILE_ASSERT(sizeof(Length) == sizeof(SameSizeAsLength), length_should_stay_small);

static TextStream& operator<<(TextStream& ts, LengthType type)
{
    switch (type) {
    case LengthType::Auto: ts << "auto"; break;
    case LengthType::Relative: ts << "relative"; break;
    case LengthType::Percent: ts << "percent"; break;
    case LengthType::Fixed: ts << "fixed"; break;
    case LengthType::Intrinsic: ts << "intrinsic"; break;
    case LengthType::MinIntrinsic: ts << "min-intrinsic"; break;
    case LengthType::MinContent: ts << "min-content"; break;
    case LengthType::MaxContent: ts << "max-content"; break;
    case LengthType::FillAvailable: ts << "fill-available"; break;
    case LengthType::FitContent: ts << "fit-content"; break;
    case LengthType::Calculated: ts << "calc"; break;
    case LengthType::Undefined: ts << "undefined"; break;
    }
    return ts;
}

TextStream& operator<<(TextStream& ts, Length length)
{
    switch (length.type()) {
    case LengthType::Auto:
    case LengthType::Undefined:
        ts << length.type();
        break;
    case LengthType::Fixed:
        ts << TextStream::FormatNumberRespectingIntegers(length.value()) << "px";
        break;
    case LengthType::Relative:
    case LengthType::Intrinsic:
    case LengthType::MinIntrinsic:
    case LengthType::MinContent:
    case LengthType::MaxContent:
    case LengthType::FillAvailable:
    case LengthType::FitContent:
        ts << length.type() << " " << TextStream::FormatNumberRespectingIntegers(length.value());
        break;
    case LengthType::Percent:
        ts << TextStream::FormatNumberRespectingIntegers(length.percent()) << "%";
        break;
    case LengthType::Calculated:
        ts << length.calculationValue();
        break;
    }
    
    if (length.hasQuirk())
        ts << " has-quirk";

    return ts;
}

} // namespace WebCore
