/*
 * Copyright (C) 2021 Tyler Wilcock <twilco.o@protonmail.com>.
 *
 * 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.
 */

#include "config.h"
#include "CSSCounterStyleRule.h"

#include "CSSPropertyParser.h"
#include "CSSStyleSheet.h"
#include "CSSTokenizer.h"
#include "Pair.h"
#include <wtf/text/StringBuilder.h>

namespace WebCore {
    
StyleRuleCounterStyle::StyleRuleCounterStyle(const AtomString& name, Ref<StyleProperties>&& properties)
    : StyleRuleBase(StyleRuleType::CounterStyle)
    , m_name(name)
    , m_properties(WTFMove(properties))
{
}

Ref<StyleRuleCounterStyle> StyleRuleCounterStyle::create(const AtomString& name, Ref<StyleProperties>&& properties)
{
    return adoptRef(*new StyleRuleCounterStyle(name, WTFMove(properties)));
}

static CounterStyleSystem toCounterStyleSystemEnum(RefPtr<CSSValue> system)
{
    if (!system || !system->isPrimitiveValue())
        return CounterStyleSystem::Symbolic;

    auto& primitiveSystemValue = downcast<CSSPrimitiveValue>(*system);
    ASSERT(primitiveSystemValue.isValueID() || primitiveSystemValue.isPair());
    CSSValueID systemKeyword = CSSValueInvalid;
    if (primitiveSystemValue.isValueID())
        systemKeyword = primitiveSystemValue.valueID();
    else if (auto* pair = primitiveSystemValue.pairValue()) {
        // This value must be `fixed` or `extends`, both of which can or must have an additional component.
        auto firstValue = pair->first();
        ASSERT(firstValue && firstValue->isValueID());
        if (firstValue)
            systemKeyword = firstValue->valueID();
    }

    switch (systemKeyword) {
    case CSSValueCyclic:
        return CounterStyleSystem::Cyclic;
    case CSSValueFixed:
        return CounterStyleSystem::Fixed;
    case CSSValueSymbolic:
        return CounterStyleSystem::Symbolic;
    case CSSValueAlphabetic:
        return CounterStyleSystem::Alphabetic;
    case CSSValueNumeric:
        return CounterStyleSystem::Numeric;
    case CSSValueAdditive:
        return CounterStyleSystem::Additive;
    case CSSValueExtends:
        return CounterStyleSystem::Extends;
    default:
        ASSERT_NOT_REACHED();
        return CounterStyleSystem::Symbolic;
    }
}

static bool symbolsValidForSystem(CounterStyleSystem system, RefPtr<CSSValue> symbols, RefPtr<CSSValue> additiveSymbols)
{
    switch (system) {
    case CounterStyleSystem::Cyclic:
    case CounterStyleSystem::Fixed:
    case CounterStyleSystem::Symbolic:
        return symbols && symbols->isValueList() && downcast<CSSValueList>(*symbols).length();
    case CounterStyleSystem::Alphabetic:
    case CounterStyleSystem::Numeric:
        return symbols && symbols->isValueList() && downcast<CSSValueList>(*symbols).length() >= 2u;
    case CounterStyleSystem::Additive:
        return additiveSymbols && additiveSymbols->isValueList() && downcast<CSSValueList>(*additiveSymbols).length();
    case CounterStyleSystem::Extends:
        return !symbols && !additiveSymbols;
    default:
        ASSERT_NOT_REACHED();
        return false;
    }
}

bool StyleRuleCounterStyle::newValueInvalidOrEqual(CSSPropertyID propertyID, const RefPtr<CSSValue> newValue) const
{
    auto currentValue = m_properties->getPropertyCSSValue(propertyID);
    if (compareCSSValuePtr(currentValue, newValue))
        return true;

    RefPtr<CSSValue> symbols;
    RefPtr<CSSValue> additiveSymbols;
    switch (propertyID) {
    case CSSPropertySystem:
        // If the attribute being set is `system`, and the new value would change the algorithm used, do nothing
        // and abort these steps.
        // (It's okay to change an aspect of the algorithm, like the first symbol value of a `fixed` system.)
        return toCounterStyleSystemEnum(currentValue) != toCounterStyleSystemEnum(newValue);
    case CSSPropertySymbols:
        symbols = newValue;
        additiveSymbols = m_properties->getPropertyCSSValue(CSSPropertyAdditiveSymbols);
        break;
    case CSSPropertyAdditiveSymbols:
        symbols = m_properties->getPropertyCSSValue(CSSPropertySymbols);
        additiveSymbols = newValue;
        break;
    default:
        return false;
    }
    auto system = m_properties->getPropertyCSSValue(CSSPropertySystem);
    return symbolsValidForSystem(toCounterStyleSystemEnum(system), symbols, additiveSymbols);
}

StyleRuleCounterStyle::~StyleRuleCounterStyle() = default;

MutableStyleProperties& StyleRuleCounterStyle::mutableProperties()
{
    if (!is<MutableStyleProperties>(m_properties))
        m_properties = m_properties->mutableCopy();
    return downcast<MutableStyleProperties>(m_properties.get());
}

Ref<CSSCounterStyleRule> CSSCounterStyleRule::create(StyleRuleCounterStyle& rule, CSSStyleSheet* sheet)
{
    return adoptRef(*new CSSCounterStyleRule(rule, sheet));
}

CSSCounterStyleRule::CSSCounterStyleRule(StyleRuleCounterStyle& counterStyleRule, CSSStyleSheet* parent)
    : CSSRule(parent)
    , m_counterStyleRule(counterStyleRule)
{
}

CSSCounterStyleRule::~CSSCounterStyleRule() = default;

String CSSCounterStyleRule::cssText() const
{
    String systemText = system();
    const char* systemPrefix = systemText.isEmpty() ? "" : " system: ";
    const char* systemSuffix = systemText.isEmpty() ? "" : ";";

    String symbolsText = symbols();
    const char* symbolsPrefix = symbolsText.isEmpty() ? "" : " symbols: ";
    const char* symbolsSuffix = symbolsText.isEmpty() ? "" : ";";

    String additiveSymbolsText = additiveSymbols();
    const char* additiveSymbolsPrefix = additiveSymbolsText.isEmpty() ? "" : " additive-symbols: ";
    const char* additiveSymbolsSuffix = additiveSymbolsText.isEmpty() ? "" : ";";

    String negativeText = negative();
    const char* negativePrefix = negativeText.isEmpty() ? "" : " negative: ";
    const char* negativeSuffix = negativeText.isEmpty() ? "" : ";";

    String prefixText = prefix();
    const char* prefixTextPrefix = prefixText.isEmpty() ? "" : " prefix: ";
    const char* prefixTextSuffix = prefixText.isEmpty() ? "" : ";";

    String suffixText = suffix();
    const char* suffixTextPrefix = suffixText.isEmpty() ? "" : " suffix: ";
    const char* suffixTextSuffix = suffixText.isEmpty() ? "" : ";";

    String padText = pad();
    const char* padPrefix = padText.isEmpty() ? "" : " pad: ";
    const char* padSuffix = padText.isEmpty() ? "" : ";";

    String rangeText = range();
    const char* rangePrefix = rangeText.isEmpty() ? "" : " range: ";
    const char* rangeSuffix = rangeText.isEmpty() ? "" : ";";

    String fallbackText = fallback();
    const char* fallbackPrefix = fallbackText.isEmpty() ? "" : " fallback: ";
    const char* fallbackSuffix = fallbackText.isEmpty() ? "" : ";";

    String speakAsText = speakAs();
    const char* speakAsPrefix = speakAsText.isEmpty() ? "" : " speak-as: ";
    const char* speakAsSuffix = speakAsText.isEmpty() ? "" : ";";

    return makeString("@counter-style ", name(), " {",
        systemPrefix, systemText, systemSuffix,
        symbolsPrefix, symbolsText, symbolsSuffix,
        additiveSymbolsPrefix, additiveSymbolsText, additiveSymbolsSuffix,
        negativePrefix, negativeText, negativeSuffix,
        prefixTextPrefix, prefixText, prefixTextSuffix,
        suffixTextPrefix, suffixText, suffixTextSuffix,
        padPrefix, padText, padSuffix,
        rangePrefix, rangeText, rangeSuffix,
        fallbackPrefix, fallbackText, fallbackSuffix,
        speakAsPrefix, speakAsText, speakAsSuffix,
    " }");
}

void CSSCounterStyleRule::reattach(StyleRuleBase& rule)
{
    m_counterStyleRule = static_cast<StyleRuleCounterStyle&>(rule);
}

// https://drafts.csswg.org/css-counter-styles-3/#dom-csscounterstylerule-name
void CSSCounterStyleRule::setName(const String& text)
{
    auto tokenizer = CSSTokenizer(text);
    auto tokenRange = tokenizer.tokenRange();
    auto name = CSSPropertyParserHelpers::consumeCounterStyleNameInPrelude(tokenRange);
    if (name.isNull() || name == m_counterStyleRule->name())
        return;

    CSSStyleSheet::RuleMutationScope mutationScope(this);
    m_counterStyleRule->setName(name);
}

void CSSCounterStyleRule::setterInternal(CSSPropertyID propertyID, const String& valueText)
{
    auto tokenizer = CSSTokenizer(valueText);
    auto tokenRange = tokenizer.tokenRange();
    auto newValue = CSSPropertyParser::parseCounterStyleDescriptor(propertyID, tokenRange, parserContext());
    if (m_counterStyleRule->newValueInvalidOrEqual(propertyID, newValue))
        return;

    CSSStyleSheet::RuleMutationScope mutationScope(this);
    m_counterStyleRule->mutableProperties().setProperty(propertyID, WTFMove(newValue));
}

void CSSCounterStyleRule::setSystem(const String& text)
{
    setterInternal(CSSPropertySystem, text);
}

void CSSCounterStyleRule::setNegative(const String& text)
{
    setterInternal(CSSPropertyNegative, text);
}

void CSSCounterStyleRule::setPrefix(const String& text)
{
    setterInternal(CSSPropertyPrefix, text);
}

void CSSCounterStyleRule::setSuffix(const String& text)
{
    setterInternal(CSSPropertySuffix, text);
}

void CSSCounterStyleRule::setRange(const String& text)
{
    setterInternal(CSSPropertyRange, text);
}

void CSSCounterStyleRule::setPad(const String& text)
{
    setterInternal(CSSPropertyPad, text);
}

void CSSCounterStyleRule::setFallback(const String& text)
{
    setterInternal(CSSPropertyFallback, text);
}

void CSSCounterStyleRule::setSymbols(const String& text)
{
    setterInternal(CSSPropertySymbols, text);
}

void CSSCounterStyleRule::setAdditiveSymbols(const String& text)
{
    setterInternal(CSSPropertyAdditiveSymbols, text);
}

void CSSCounterStyleRule::setSpeakAs(const String& text)
{
    setterInternal(CSSPropertySpeakAs, text);
}

} // namespace WebCore
