/*
 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
 * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
 * Copyright (C) 2013 Intel Corporation. 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 "core/css/StylePropertySerializer.h"

#include "core/CSSValueKeywords.h"
#include "core/StylePropertyShorthand.h"
#include "core/css/CSSCustomPropertyDeclaration.h"
#include "core/css/CSSPropertyMetadata.h"
#include "core/css/CSSValuePool.h"
#include "wtf/BitArray.h"
#include "wtf/text/StringBuilder.h"

namespace blink {

static bool isInitialOrInherit(const String& value)
{
    DEFINE_STATIC_LOCAL(String, initial, ("initial"));
    DEFINE_STATIC_LOCAL(String, inherit, ("inherit"));
    return value.length() == 7 && (value == initial || value == inherit);
}

StylePropertySerializer::StylePropertySetForSerializer::StylePropertySetForSerializer(const StylePropertySet& properties)
    : m_propertySet(&properties)
    , m_allIndex(m_propertySet->findPropertyIndex(CSSPropertyAll))
    , m_needToExpandAll(false)
{
    if (!hasAllProperty())
        return;

    StylePropertySet::PropertyReference allProperty = m_propertySet->propertyAt(m_allIndex);
    for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i) {
        StylePropertySet::PropertyReference property = m_propertySet->propertyAt(i);
        if (CSSProperty::isAffectedByAllProperty(property.id())) {
            if (allProperty.isImportant() && !property.isImportant())
                continue;
            if (static_cast<unsigned>(m_allIndex) >= i)
                continue;
            if (property.value()->equals(*allProperty.value())
                && property.isImportant() == allProperty.isImportant())
                continue;
            m_needToExpandAll = true;
        }
        m_longhandPropertyUsed.set(property.id() - firstCSSProperty);
    }
}

DEFINE_TRACE(StylePropertySerializer::StylePropertySetForSerializer)
{
    visitor->trace(m_propertySet);
}

unsigned StylePropertySerializer::StylePropertySetForSerializer::propertyCount() const
{
    if (!hasExpandedAllProperty())
        return m_propertySet->propertyCount();
    return lastCSSProperty - firstCSSProperty + 1;
}

StylePropertySerializer::PropertyValueForSerializer StylePropertySerializer::StylePropertySetForSerializer::propertyAt(unsigned index) const
{
    if (!hasExpandedAllProperty())
        return StylePropertySerializer::PropertyValueForSerializer(m_propertySet->propertyAt(index));

    CSSPropertyID propertyID = static_cast<CSSPropertyID>(index + firstCSSProperty);
    ASSERT(firstCSSProperty <= propertyID && propertyID <= lastCSSProperty);
    if (m_longhandPropertyUsed.get(index)) {
        int index = m_propertySet->findPropertyIndex(propertyID);
        ASSERT(index != -1);
        return StylePropertySerializer::PropertyValueForSerializer(m_propertySet->propertyAt(index));
    }

    StylePropertySet::PropertyReference property = m_propertySet->propertyAt(m_allIndex);
    return StylePropertySerializer::PropertyValueForSerializer(propertyID, property.value(), property.isImportant());
}

bool StylePropertySerializer::StylePropertySetForSerializer::shouldProcessPropertyAt(unsigned index) const
{
    // StylePropertySet has all valid longhands. We should process.
    if (!hasAllProperty())
        return true;

    // If all is not expanded, we need to process "all" and properties which
    // are not overwritten by "all".
    if (!m_needToExpandAll) {
        StylePropertySet::PropertyReference property = m_propertySet->propertyAt(index);
        if (property.id() == CSSPropertyAll || !CSSProperty::isAffectedByAllProperty(property.id()))
            return true;
        return m_longhandPropertyUsed.get(property.id() - firstCSSProperty);
    }

    CSSPropertyID propertyID = static_cast<CSSPropertyID>(index + firstCSSProperty);
    ASSERT(firstCSSProperty <= propertyID && propertyID <= lastCSSProperty);

    // Since "all" is expanded, we don't need to process "all".
    // We should not process expanded shorthands (e.g. font, background,
    // and so on) either.
    if (isShorthandProperty(propertyID) || propertyID == CSSPropertyAll)
        return false;

    // The all property is a shorthand that resets all CSS properties except
    // direction and unicode-bidi. It only accepts the CSS-wide keywords.
    // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
    if (!CSSProperty::isAffectedByAllProperty(propertyID))
        return m_longhandPropertyUsed.get(index);

    return true;
}

int StylePropertySerializer::StylePropertySetForSerializer::findPropertyIndex(CSSPropertyID propertyID) const
{
    if (!hasExpandedAllProperty())
        return m_propertySet->findPropertyIndex(propertyID);
    return propertyID - firstCSSProperty;
}

const CSSValue* StylePropertySerializer::StylePropertySetForSerializer::getPropertyCSSValue(CSSPropertyID propertyID) const
{
    int index = findPropertyIndex(propertyID);
    if (index == -1)
        return nullptr;
    StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index);
    return value.value();
}

String StylePropertySerializer::StylePropertySetForSerializer::getPropertyValue(CSSPropertyID propertyID) const
{
    if (!hasExpandedAllProperty())
        return m_propertySet->getPropertyValue(propertyID);

    const CSSValue* value = getPropertyCSSValue(propertyID);
    if (!value)
        return String();
    return value->cssText();
}

bool StylePropertySerializer::StylePropertySetForSerializer::isPropertyImplicit(CSSPropertyID propertyID) const
{
    int index = findPropertyIndex(propertyID);
    if (index == -1)
        return false;
    StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index);
    return value.isImplicit();
}

bool StylePropertySerializer::StylePropertySetForSerializer::propertyIsImportant(CSSPropertyID propertyID) const
{
    int index = findPropertyIndex(propertyID);
    if (index == -1)
        return false;
    StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index);
    return value.isImportant();
}

StylePropertySerializer::StylePropertySerializer(const StylePropertySet& properties)
    : m_propertySet(properties)
{
}

String StylePropertySerializer::getCustomPropertyText(const PropertyValueForSerializer& property, bool isNotFirstDecl) const
{
    ASSERT(property.id() == CSSPropertyVariable);
    StringBuilder result;
    if (isNotFirstDecl)
        result.append(' ');
    const CSSCustomPropertyDeclaration* value = toCSSCustomPropertyDeclaration(property.value());
    result.append(value->name());
    result.append(':');
    result.append(value->customCSSText());
    if (property.isImportant())
        result.appendLiteral(" !important");
    result.append(';');
    return result.toString();
}

static String getApplyAtRuleText(const CSSValue* value, bool isNotFirstDecl)
{
    StringBuilder result;
    if (isNotFirstDecl)
        result.append(' ');
    result.appendLiteral("@apply ");
    result.append(toCSSCustomIdentValue(value)->value());
    result.append(';');
    return result.toString();
}

String StylePropertySerializer::getPropertyText(CSSPropertyID propertyID, const String& value, bool isImportant, bool isNotFirstDecl) const
{
    StringBuilder result;
    if (isNotFirstDecl)
        result.append(' ');
    result.append(getPropertyName(propertyID));
    result.appendLiteral(": ");
    result.append(value);
    if (isImportant)
        result.appendLiteral(" !important");
    result.append(';');
    return result.toString();
}

String StylePropertySerializer::asText() const
{
    StringBuilder result;

    BitArray<numCSSProperties> shorthandPropertyUsed;
    BitArray<numCSSProperties> shorthandPropertyAppeared;

    unsigned size = m_propertySet.propertyCount();
    unsigned numDecls = 0;
    for (unsigned n = 0; n < size; ++n) {
        if (!m_propertySet.shouldProcessPropertyAt(n))
            continue;

        StylePropertySerializer::PropertyValueForSerializer property = m_propertySet.propertyAt(n);
        CSSPropertyID propertyID = property.id();
        // Only enabled properties should be part of the style.
        ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID));
        CSSPropertyID shorthandPropertyID = CSSPropertyInvalid;
        CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid;
        String value;
        // Shorthands with variable references are not expanded at parse time
        // and hence may still be observed during serialization.
        ASSERT(!isShorthandProperty(propertyID) || property.value()->isVariableReferenceValue());

        switch (propertyID) {
        case CSSPropertyBackgroundAttachment:
        case CSSPropertyBackgroundClip:
        case CSSPropertyBackgroundColor:
        case CSSPropertyBackgroundImage:
        case CSSPropertyBackgroundOrigin:
        case CSSPropertyBackgroundPositionX:
        case CSSPropertyBackgroundPositionY:
        case CSSPropertyBackgroundSize:
        case CSSPropertyBackgroundRepeatX:
        case CSSPropertyBackgroundRepeatY:
            shorthandPropertyAppeared.set(CSSPropertyBackground - firstCSSProperty);
            continue;
        case CSSPropertyBorderTopWidth:
        case CSSPropertyBorderRightWidth:
        case CSSPropertyBorderBottomWidth:
        case CSSPropertyBorderLeftWidth:
            if (!borderFallbackShorthandProperty)
                borderFallbackShorthandProperty = CSSPropertyBorderWidth;
        case CSSPropertyBorderTopStyle:
        case CSSPropertyBorderRightStyle:
        case CSSPropertyBorderBottomStyle:
        case CSSPropertyBorderLeftStyle:
            if (!borderFallbackShorthandProperty)
                borderFallbackShorthandProperty = CSSPropertyBorderStyle;
        case CSSPropertyBorderTopColor:
        case CSSPropertyBorderRightColor:
        case CSSPropertyBorderBottomColor:
        case CSSPropertyBorderLeftColor:
            if (!borderFallbackShorthandProperty)
                borderFallbackShorthandProperty = CSSPropertyBorderColor;

            // FIXME: Deal with cases where only some of border-(top|right|bottom|left) are specified.
            if (!shorthandPropertyAppeared.get(CSSPropertyBorder - firstCSSProperty)) {
                value = borderPropertyValue(ReturnNullOnUncommonValues);
                if (value.isNull())
                    shorthandPropertyAppeared.set(CSSPropertyBorder - firstCSSProperty);
                else
                    shorthandPropertyID = CSSPropertyBorder;
            } else if (shorthandPropertyUsed.get(CSSPropertyBorder - firstCSSProperty)) {
                shorthandPropertyID = CSSPropertyBorder;
            }
            if (!shorthandPropertyID)
                shorthandPropertyID = borderFallbackShorthandProperty;
            break;
        case CSSPropertyBorderTopLeftRadius:
        case CSSPropertyBorderTopRightRadius:
        case CSSPropertyBorderBottomLeftRadius:
        case CSSPropertyBorderBottomRightRadius:
            shorthandPropertyID = CSSPropertyBorderRadius;
            break;
        case CSSPropertyWebkitBorderHorizontalSpacing:
        case CSSPropertyWebkitBorderVerticalSpacing:
            shorthandPropertyID = CSSPropertyBorderSpacing;
            break;
        case CSSPropertyFontFamily:
        case CSSPropertyLineHeight:
        case CSSPropertyFontSize:
        case CSSPropertyFontStretch:
        case CSSPropertyFontStyle:
        case CSSPropertyFontVariant:
        case CSSPropertyFontWeight:
            // Don't use CSSPropertyFont because old UAs can't recognize them but are important for editing.
            break;
        case CSSPropertyListStyleType:
        case CSSPropertyListStylePosition:
        case CSSPropertyListStyleImage:
            shorthandPropertyID = CSSPropertyListStyle;
            break;
        case CSSPropertyMarginTop:
        case CSSPropertyMarginRight:
        case CSSPropertyMarginBottom:
        case CSSPropertyMarginLeft:
            shorthandPropertyID = CSSPropertyMargin;
            break;
        case CSSPropertyMotionPath:
        case CSSPropertyMotionOffset:
        case CSSPropertyMotionRotation:
            shorthandPropertyID = CSSPropertyMotion;
            break;
        case CSSPropertyOutlineWidth:
        case CSSPropertyOutlineStyle:
        case CSSPropertyOutlineColor:
            shorthandPropertyID = CSSPropertyOutline;
            break;
        case CSSPropertyOverflowX:
        case CSSPropertyOverflowY:
            shorthandPropertyID = CSSPropertyOverflow;
            break;
        case CSSPropertyPaddingTop:
        case CSSPropertyPaddingRight:
        case CSSPropertyPaddingBottom:
        case CSSPropertyPaddingLeft:
            shorthandPropertyID = CSSPropertyPadding;
            break;
        case CSSPropertyTransitionProperty:
        case CSSPropertyTransitionDuration:
        case CSSPropertyTransitionTimingFunction:
        case CSSPropertyTransitionDelay:
            shorthandPropertyID = CSSPropertyTransition;
            break;
        case CSSPropertyAnimationName:
        case CSSPropertyAnimationDuration:
        case CSSPropertyAnimationTimingFunction:
        case CSSPropertyAnimationDelay:
        case CSSPropertyAnimationIterationCount:
        case CSSPropertyAnimationDirection:
        case CSSPropertyAnimationFillMode:
        case CSSPropertyAnimationPlayState:
            shorthandPropertyID = CSSPropertyAnimation;
            break;
        case CSSPropertyFlexDirection:
        case CSSPropertyFlexWrap:
            shorthandPropertyID = CSSPropertyFlexFlow;
            break;
        case CSSPropertyFlexBasis:
        case CSSPropertyFlexGrow:
        case CSSPropertyFlexShrink:
            shorthandPropertyID = CSSPropertyFlex;
            break;
        case CSSPropertyWebkitMaskPositionX:
        case CSSPropertyWebkitMaskPositionY:
        case CSSPropertyWebkitMaskRepeatX:
        case CSSPropertyWebkitMaskRepeatY:
        case CSSPropertyWebkitMaskImage:
        case CSSPropertyWebkitMaskRepeat:
        case CSSPropertyWebkitMaskPosition:
        case CSSPropertyWebkitMaskClip:
        case CSSPropertyWebkitMaskOrigin:
            shorthandPropertyID = CSSPropertyWebkitMask;
            break;
        case CSSPropertyVariable:
            result.append(getCustomPropertyText(property, numDecls++));
            continue;
        case CSSPropertyAll:
            result.append(getPropertyText(propertyID, property.value()->cssText(), property.isImportant(), numDecls++));
            continue;
        case CSSPropertyApplyAtRule:
            result.append(getApplyAtRuleText(property.value(), numDecls++));
            continue;
        default:
            break;
        }

        unsigned shortPropertyIndex = shorthandPropertyID - firstCSSProperty;
        if (shorthandPropertyID) {
            if (shorthandPropertyUsed.get(shortPropertyIndex))
                continue;
            if (!shorthandPropertyAppeared.get(shortPropertyIndex) && value.isNull())
                value = m_propertySet.getPropertyValue(shorthandPropertyID);
            shorthandPropertyAppeared.set(shortPropertyIndex);
        }

        if (!value.isNull()) {
            if (shorthandPropertyID) {
                propertyID = shorthandPropertyID;
                shorthandPropertyUsed.set(shortPropertyIndex);
            }
        } else {
            // We should not show "initial" when the "initial" is implicit.
            // If explicit "initial", we need to show.
            if (property.value()->isImplicitInitialValue())
                continue;
            value = property.value()->cssText();
        }

        result.append(getPropertyText(propertyID, value, property.isImportant(), numDecls++));
    }

    if (shorthandPropertyAppeared.get(CSSPropertyBackground - firstCSSProperty))
        appendBackgroundPropertyAsText(result, numDecls);

    ASSERT(!numDecls ^ !result.isEmpty());
    return result.toString();
}

String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
{
    // Shorthand and 4-values properties
    switch (propertyID) {
    case CSSPropertyAnimation:
        return getLayeredShorthandValue(animationShorthand());
    case CSSPropertyBorderSpacing:
        return borderSpacingValue(borderSpacingShorthand());
    case CSSPropertyBackgroundPosition:
        return getLayeredShorthandValue(backgroundPositionShorthand());
    case CSSPropertyBackgroundRepeat:
        return backgroundRepeatPropertyValue();
    case CSSPropertyBackground:
        return getLayeredShorthandValue(backgroundShorthand());
    case CSSPropertyBorder:
        return borderPropertyValue(OmitUncommonValues);
    case CSSPropertyBorderTop:
        return getShorthandValue(borderTopShorthand());
    case CSSPropertyBorderRight:
        return getShorthandValue(borderRightShorthand());
    case CSSPropertyBorderBottom:
        return getShorthandValue(borderBottomShorthand());
    case CSSPropertyBorderLeft:
        return getShorthandValue(borderLeftShorthand());
    case CSSPropertyOutline:
        return getShorthandValue(outlineShorthand());
    case CSSPropertyBorderColor:
        return get4Values(borderColorShorthand());
    case CSSPropertyBorderWidth:
        return get4Values(borderWidthShorthand());
    case CSSPropertyBorderStyle:
        return get4Values(borderStyleShorthand());
    case CSSPropertyColumnRule:
        return getShorthandValue(columnRuleShorthand());
    case CSSPropertyColumns:
        return getShorthandValue(columnsShorthand());
    case CSSPropertyFlex:
        return getShorthandValue(flexShorthand());
    case CSSPropertyFlexFlow:
        return getShorthandValue(flexFlowShorthand());
    case CSSPropertyGridColumn:
        return getShorthandValue(gridColumnShorthand(), " / ");
    case CSSPropertyGridRow:
        return getShorthandValue(gridRowShorthand(), " / ");
    case CSSPropertyGridArea:
        return getShorthandValue(gridAreaShorthand(), " / ");
    case CSSPropertyGridGap:
        return getShorthandValue(gridGapShorthand());
    case CSSPropertyFont:
        return fontValue();
    case CSSPropertyMargin:
        return get4Values(marginShorthand());
    case CSSPropertyMotion:
        return getShorthandValue(motionShorthand());
    case CSSPropertyWebkitMarginCollapse:
        return getShorthandValue(webkitMarginCollapseShorthand());
    case CSSPropertyOverflow:
        return getCommonValue(overflowShorthand());
    case CSSPropertyPadding:
        return get4Values(paddingShorthand());
    case CSSPropertyTransition:
        return getLayeredShorthandValue(transitionShorthand());
    case CSSPropertyListStyle:
        return getShorthandValue(listStyleShorthand());
    case CSSPropertyWebkitMaskPosition:
        return getLayeredShorthandValue(webkitMaskPositionShorthand());
    case CSSPropertyWebkitMaskRepeat:
        return getLayeredShorthandValue(webkitMaskRepeatShorthand());
    case CSSPropertyWebkitMask:
        return getLayeredShorthandValue(webkitMaskShorthand());
    case CSSPropertyWebkitTextEmphasis:
        return getShorthandValue(webkitTextEmphasisShorthand());
    case CSSPropertyWebkitTextStroke:
        return getShorthandValue(webkitTextStrokeShorthand());
    case CSSPropertyMarker: {
        if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyMarkerStart))
            return value->cssText();
        return String();
    }
    case CSSPropertyBorderRadius:
        return get4Values(borderRadiusShorthand());
    default:
        return String();
    }
}

String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand& shorthand) const
{
    const CSSValue* horizontalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[0]);
    const CSSValue* verticalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[1]);

    // While standard border-spacing property does not allow specifying border-spacing-vertical without
    // specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.html#separated-borders>,
    // -webkit-border-spacing-vertical can be set without -webkit-border-spacing-horizontal.
    if (!horizontalValue || !verticalValue)
        return String();

    String horizontalValueCSSText = horizontalValue->cssText();
    String verticalValueCSSText = verticalValue->cssText();
    if (horizontalValueCSSText == verticalValueCSSText)
        return horizontalValueCSSText;
    return horizontalValueCSSText + ' ' + verticalValueCSSText;
}

void StylePropertySerializer::appendFontLonghandValueIfNotNormal(CSSPropertyID propertyID, StringBuilder& result, String& commonValue) const
{
    int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID);
    ASSERT(foundPropertyIndex != -1);

    const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value();
    if (val->isPrimitiveValue() && toCSSPrimitiveValue(val)->getValueID() == CSSValueNormal) {
        commonValue = String();
        return;
    }

    char prefix = '\0';
    switch (propertyID) {
    case CSSPropertyFontStyle:
        break; // No prefix.
    case CSSPropertyFontFamily:
    case CSSPropertyFontStretch:
    case CSSPropertyFontVariant:
    case CSSPropertyFontWeight:
        prefix = ' ';
        break;
    case CSSPropertyLineHeight:
        prefix = '/';
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    if (prefix && !result.isEmpty())
        result.append(prefix);
    String value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText();
    result.append(value);
    if (!commonValue.isNull() && commonValue != value)
        commonValue = String();
}

String StylePropertySerializer::fontValue() const
{
    if (!isPropertyShorthandAvailable(fontShorthand()) && !shorthandHasOnlyInitialOrInheritedValue(fontShorthand()))
        return emptyString();

    int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontSize);
    int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontFamily);
    ASSERT(fontSizePropertyIndex != -1 && fontFamilyPropertyIndex != -1);

    PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontSizePropertyIndex);
    PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fontFamilyPropertyIndex);

    String commonValue = fontSizeProperty.value()->cssText();
    StringBuilder result;
    appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result, commonValue);
    appendFontLonghandValueIfNotNormal(CSSPropertyFontVariant, result, commonValue);
    appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result, commonValue);
    appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result, commonValue);
    if (!result.isEmpty())
        result.append(' ');
    result.append(fontSizeProperty.value()->cssText());
    appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result, commonValue);
    if (!result.isEmpty())
        result.append(' ');
    result.append(fontFamilyProperty.value()->cssText());
    if (isInitialOrInherit(commonValue))
        return commonValue;
    return result.toString();
}

String StylePropertySerializer::get4Values(const StylePropertyShorthand& shorthand) const
{
    // Assume the properties are in the usual order top, right, bottom, left.
    int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0]);
    int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[1]);
    int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[2]);
    int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[3]);

    if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 || leftValueIndex == -1)
        return String();

    PropertyValueForSerializer top = m_propertySet.propertyAt(topValueIndex);
    PropertyValueForSerializer right = m_propertySet.propertyAt(rightValueIndex);
    PropertyValueForSerializer bottom = m_propertySet.propertyAt(bottomValueIndex);
    PropertyValueForSerializer left = m_propertySet.propertyAt(leftValueIndex);

    // All 4 properties must be specified.
    if (!top.value() || !right.value() || !bottom.value() || !left.value())
        return String();

    if (top.isImportant() != right.isImportant() || right.isImportant() != bottom.isImportant() || bottom.isImportant() != left.isImportant())
        return String();

    if (top.isInherited() && right.isInherited() && bottom.isInherited() && left.isInherited())
        return getValueName(CSSValueInherit);

    unsigned numInitial = top.value()->isInitialValue() + right.value()->isInitialValue() + bottom.value()->isInitialValue() + left.value()->isInitialValue();
    if (numInitial == 4)
        return getValueName(CSSValueInitial);
    if (numInitial > 0)
        return String();

    bool showLeft = !right.value()->equals(*left.value());
    bool showBottom = !top.value()->equals(*bottom.value()) || showLeft;
    bool showRight = !top.value()->equals(*right.value()) || showBottom;

    StringBuilder result;
    result.append(top.value()->cssText());
    if (showRight) {
        result.append(' ');
        result.append(right.value()->cssText());
    }
    if (showBottom) {
        result.append(' ');
        result.append(bottom.value()->cssText());
    }
    if (showLeft) {
        result.append(' ');
        result.append(left.value()->cssText());
    }
    return result.toString();
}

String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShorthand& shorthand) const
{
    const unsigned size = shorthand.length();

    // Begin by collecting the properties into a vector.
    WillBeHeapVector<RawPtrWillBeMember<const CSSValue>> values(size);
    // If the below loop succeeds, there should always be at minimum 1 layer.
    size_t numLayers = 1U;

    for (size_t i = 0; i < size; i++) {
        values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
        // A shorthand is not available if getPropertyCSSValue didn't resolve to anything.
        if (!values[i])
            return String();
        if (values[i]->isBaseValueList()) {
            const CSSValueList* valueList = toCSSValueList(values[i]);
            numLayers = std::max(numLayers, valueList->length());
        }
    }

    StringBuilder result;
    // Tracks whether or not all the values are initial or all the values are inherit.
    // Start out assuming there is a common value. It will get set to false below if there isn't one.
    bool hasCommonValue = true;
    const CSSValue* commonValue = nullptr;

    // Now stitch the properties together. Implicit initial values are flagged as such and
    // can safely be omitted.
    for (size_t layer = 0; layer < numLayers; layer++) {
        StringBuilder layerResult;
        bool useRepeatXShorthand = false;
        bool useRepeatYShorthand = false;
        bool useSingleWordShorthand = false;
        bool foundPositionXCSSProperty = false;
        bool foundPositionYCSSProperty = false;

        for (unsigned propertyIndex = 0; propertyIndex < size; propertyIndex++) {
            const CSSValue* value = nullptr;
            CSSPropertyID property = shorthand.properties()[propertyIndex];

            // Get a CSSValue for this property and layer.
            if (values[propertyIndex]->isBaseValueList()) {
                // Might return 0 if there is not an item for this layer for this property.
                value = toCSSValueList(values[propertyIndex])->itemWithBoundsCheck(layer);
            } else if (layer == 0 || (layer != numLayers - 1 && property == CSSPropertyBackgroundColor)) {
                // Singletons except background color belong in the 0th layer.
                // Background color belongs in the last layer.
                value = values[propertyIndex];
            }
            // No point proceeding if there's not a value to look at.
            if (!value)
                continue;

            // Special case for background-repeat.
            if ((propertyIndex < size - 1 && m_propertySet.isPropertyImplicit(property))
                && (property == CSSPropertyBackgroundRepeatX || property == CSSPropertyWebkitMaskRepeatX)) {
                ASSERT(shorthand.properties()[propertyIndex + 1] == CSSPropertyBackgroundRepeatY
                    || shorthand.properties()[propertyIndex + 1] == CSSPropertyWebkitMaskRepeatY);
                const CSSValue* yValue = values[propertyIndex + 1]->isValueList() ?
                    toCSSValueList(values[propertyIndex + 1])->item(layer) : values[propertyIndex + 1].get();


                // FIXME: At some point we need to fix this code to avoid returning an invalid shorthand,
                // since some longhand combinations are not serializable into a single shorthand.
                if (!value->isPrimitiveValue() || !yValue->isPrimitiveValue())
                    continue;

                CSSValueID xId = toCSSPrimitiveValue(value)->getValueID();
                CSSValueID yId = toCSSPrimitiveValue(yValue)->getValueID();
                // Maybe advance propertyIndex to look at the next CSSValue in the list for the checks below.
                if (xId == yId) {
                    useSingleWordShorthand = true;
                    property = shorthand.properties()[++propertyIndex];
                } else if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) {
                    useRepeatXShorthand = true;
                    property = shorthand.properties()[++propertyIndex];
                } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) {
                    useRepeatYShorthand = true;
                    property = shorthand.properties()[++propertyIndex];
                }
            }

            if (!(value->isInitialValue() && toCSSInitialValue(value)->isImplicit())) {
                if (property == CSSPropertyBackgroundSize || property == CSSPropertyWebkitMaskSize) {
                    if (foundPositionYCSSProperty || foundPositionXCSSProperty)
                        layerResult.appendLiteral(" / ");
                    else
                        layerResult.appendLiteral(" 0% 0% / ");
                } else if (!layerResult.isEmpty()) {
                    // Do this second to avoid ending up with an extra space in the output if we hit the continue above.
                    layerResult.append(' ');
                }

                if (useRepeatXShorthand) {
                    useRepeatXShorthand = false;
                    layerResult.append(getValueName(CSSValueRepeatX));
                } else if (useRepeatYShorthand) {
                    useRepeatYShorthand = false;
                    layerResult.append(getValueName(CSSValueRepeatY));
                } else {
                    if (useSingleWordShorthand)
                        useSingleWordShorthand = false;
                    layerResult.append(value->cssText());
                }
                if (property == CSSPropertyBackgroundPositionX || property == CSSPropertyWebkitMaskPositionX)
                    foundPositionXCSSProperty = true;
                if (property == CSSPropertyBackgroundPositionY || property == CSSPropertyWebkitMaskPositionY) {
                    foundPositionYCSSProperty = true;
                    // background-position is a special case. If only the first offset is specified,
                    // the second one defaults to "center", not the same value.
                    if (hasCommonValue && !value->isInitialValue() && !value->isInheritedValue())
                        hasCommonValue = false;
                }
            }

            if (hasCommonValue && !commonValue)
                commonValue = value;
            else if (!value->equals(*commonValue))
                hasCommonValue = false;
        }
        if (!layerResult.isEmpty()) {
            if (!result.isEmpty())
                result.appendLiteral(", ");
            result.append(layerResult);
        }
    }

    if (hasCommonValue && (commonValue->isInitialValue() || commonValue->isInheritedValue()))
        return commonValue->cssText();

    return result.toString();
}

String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand& shorthand, String separator) const
{
    String commonValue;
    StringBuilder result;
    for (unsigned i = 0; i < shorthand.length(); ++i) {
        const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
        if (!value)
            return String();
        String valueText = value->cssText();
        if (!i)
            commonValue = valueText;
        else if (!commonValue.isNull() && commonValue != valueText)
            commonValue = String();
        if (value->isInitialValue())
            continue;
        if (!result.isEmpty())
            result.append(separator);
        result.append(valueText);
    }
    if (isInitialOrInherit(commonValue))
        return commonValue;
    return result.toString();
}

// only returns a non-null value if all properties have the same, non-null value
String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& shorthand) const
{
    String res;
    bool lastPropertyWasImportant = false;
    for (unsigned i = 0; i < shorthand.length(); ++i) {
        const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
        // FIXME: CSSInitialValue::cssText should generate the right value.
        if (!value)
            return String();
        String text = value->cssText();
        if (text.isNull())
            return String();
        if (res.isNull())
            res = text;
        else if (res != text)
            return String();

        bool currentPropertyIsImportant = m_propertySet.propertyIsImportant(shorthand.properties()[i]);
        if (i && lastPropertyWasImportant != currentPropertyIsImportant)
            return String();
        lastPropertyWasImportant = currentPropertyIsImportant;
    }
    return res;
}

String StylePropertySerializer::borderPropertyValue(CommonValueMode valueMode) const
{
    const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand() };
    String commonValue;
    StringBuilder result;
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
        String value = getCommonValue(properties[i]);
        if (value.isNull()) {
            if (valueMode == ReturnNullOnUncommonValues)
                return String();
            ASSERT(valueMode == OmitUncommonValues);
            continue;
        }
        if (!i)
            commonValue = value;
        else if (!commonValue.isNull() && commonValue != value)
            commonValue = String();
        if (value == "initial")
            continue;
        if (!result.isEmpty())
            result.append(' ');
        result.append(value);
    }
    if (isInitialOrInherit(commonValue))
        return commonValue;
    return result.isEmpty() ? String() : result.toString();
}

static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue& repeatXCSSValue, const CSSValue& repeatYCSSValue)
{
    // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS.
    DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValue::createIdentifier(CSSValueRepeat)));
    const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? *initialRepeatValue : toCSSPrimitiveValue(repeatXCSSValue);
    const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? *initialRepeatValue : toCSSPrimitiveValue(repeatYCSSValue);
    CSSValueID repeatXValueId = repeatX.getValueID();
    CSSValueID repeatYValueId = repeatY.getValueID();
    if (repeatXValueId == repeatYValueId) {
        builder.append(repeatX.cssText());
    } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueRepeat) {
        builder.appendLiteral("repeat-y");
    } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoRepeat) {
        builder.appendLiteral("repeat-x");
    } else {
        builder.append(repeatX.cssText());
        builder.appendLiteral(" ");
        builder.append(repeatY.cssText());
    }
}

String StylePropertySerializer::backgroundRepeatPropertyValue() const
{
    const CSSValue* repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatX);
    const CSSValue* repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatY);
    if (!repeatX || !repeatY)
        return String();
    if (m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX) != m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatY))
        return String();
    if ((repeatX->isInitialValue() && repeatY->isInitialValue()) || (repeatX->isInheritedValue() && repeatY->isInheritedValue()))
        return repeatX->cssText();

    const CSSValueList* repeatXList = 0;
    int repeatXLength = 1;
    if (repeatX->isValueList()) {
        repeatXList = toCSSValueList(repeatX);
        repeatXLength = repeatXList->length();
    } else if (!repeatX->isPrimitiveValue()) {
        return String();
    }

    const CSSValueList* repeatYList = 0;
    int repeatYLength = 1;
    if (repeatY->isValueList()) {
        repeatYList = toCSSValueList(repeatY);
        repeatYLength = repeatYList->length();
    } else if (!repeatY->isPrimitiveValue()) {
        return String();
    }

    size_t shorthandLength = lowestCommonMultiple(repeatXLength, repeatYLength);
    StringBuilder builder;
    for (size_t i = 0; i < shorthandLength; ++i) {
        if (i)
            builder.appendLiteral(", ");

        const CSSValue* xValue = repeatXList ? repeatXList->item(i % repeatXList->length()) : repeatX;
        const CSSValue* yValue = repeatYList ? repeatYList->item(i % repeatYList->length()) : repeatY;
        appendBackgroundRepeatValue(builder, *xValue, *yValue);
    }
    return builder.toString();
}

void StylePropertySerializer::appendBackgroundPropertyAsText(StringBuilder& result, unsigned& numDecls) const
{
    if (isPropertyShorthandAvailable(backgroundShorthand())) {
        String backgroundValue = getPropertyValue(CSSPropertyBackground);
        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundImage);
        result.append(getPropertyText(CSSPropertyBackground, backgroundValue, isImportant, numDecls++));
        return;
    }
    if (shorthandHasOnlyInitialOrInheritedValue(backgroundShorthand())) {
        const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundImage);
        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundImage);
        result.append(getPropertyText(CSSPropertyBackground, value->cssText(), isImportant, numDecls++));
        return;
    }

    // backgroundShorthandProperty without layered shorhand properties
    const CSSPropertyID backgroundPropertyIds[] = {
        CSSPropertyBackgroundImage,
        CSSPropertyBackgroundAttachment,
        CSSPropertyBackgroundColor,
        CSSPropertyBackgroundSize,
        CSSPropertyBackgroundOrigin,
        CSSPropertyBackgroundClip
    };

    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(backgroundPropertyIds); ++i) {
        CSSPropertyID propertyID = backgroundPropertyIds[i];
        const CSSValue* value = m_propertySet.getPropertyCSSValue(propertyID);
        if (!value)
            continue;
        result.append(getPropertyText(propertyID, value->cssText(), m_propertySet.propertyIsImportant(propertyID), numDecls++));
    }

    // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output.
    // It is required because background-position-x/y are non-standard properties and WebKit generated output
    // would not work in Firefox (<rdar://problem/5143183>)
    // It would be a better solution if background-position was UnitType::Pair.
    if (shorthandHasOnlyInitialOrInheritedValue(backgroundPositionShorthand())) {
        const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX);
        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
        result.append(getPropertyText(CSSPropertyBackgroundPosition, value->cssText(), isImportant, numDecls++));
    } else if (isPropertyShorthandAvailable(backgroundPositionShorthand())) {
        String positionValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundPosition);
        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
        if (!positionValue.isNull())
            result.append(getPropertyText(CSSPropertyBackgroundPosition, positionValue, isImportant, numDecls++));
    } else {
        // should check background-position-x or background-position-y.
        if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX)) {
            if (!value->isImplicitInitialValue()) {
                bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
                result.append(getPropertyText(CSSPropertyBackgroundPositionX, value->cssText(), isImportant, numDecls++));
            }
        }
        if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionY)) {
            if (!value->isImplicitInitialValue()) {
                bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionY);
                result.append(getPropertyText(CSSPropertyBackgroundPositionY, value->cssText(), isImportant, numDecls++));
            }
        }
    }

    String repeatValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundRepeat);
    if (!repeatValue.isNull())
        result.append(getPropertyText(CSSPropertyBackgroundRepeat, repeatValue, m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX), numDecls++));
}

bool StylePropertySerializer::isPropertyShorthandAvailable(const StylePropertyShorthand& shorthand) const
{
    ASSERT(shorthand.length() > 0);

    bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[0]);
    for (unsigned i = 0; i < shorthand.length(); ++i) {
        const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
        if (!value || (value->isInitialValue() && !value->isImplicitInitialValue()) || value->isInheritedValue())
            return false;
        if (isImportant != m_propertySet.propertyIsImportant(shorthand.properties()[i]))
            return false;
    }
    return true;
}

bool StylePropertySerializer::shorthandHasOnlyInitialOrInheritedValue(const StylePropertyShorthand& shorthand) const
{
    ASSERT(shorthand.length() > 0);
    bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[0]);
    bool isInitialValue = true;
    bool isInheritedValue = true;
    for (unsigned i = 0; i < shorthand.length(); ++i) {
        const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
        if (!value)
            return false;
        if (!value->isInitialValue())
            isInitialValue = false;
        if (!value->isInheritedValue())
            isInheritedValue = false;
        if (isImportant != m_propertySet.propertyIsImportant(shorthand.properties()[i]))
            return false;
    }
    return isInitialValue || isInheritedValue;
}

} // namespace blink
