/*
 * Copyright (C) 2022 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,
 * 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 "ContainerQuery.h"

#include "CSSMarkup.h"
#include "CSSValue.h"
#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringBuilder.h>

namespace WebCore {
namespace CQ {
namespace FeatureNames {

const AtomString& width()
{
    static MainThreadNeverDestroyed<AtomString> name { "width"_s };
    return name;
}

const AtomString& height()
{
    static MainThreadNeverDestroyed<AtomString> name { "height"_s };
    return name;
}

const AtomString& inlineSize()
{
    static MainThreadNeverDestroyed<AtomString> name { "inline-size"_s };
    return name;
}

const AtomString& blockSize()
{
    static MainThreadNeverDestroyed<AtomString> name { "block-size"_s };
    return name;
}

const AtomString& aspectRatio()
{
    static MainThreadNeverDestroyed<AtomString> name { "aspect-ratio"_s };
    return name;
}

const AtomString& orientation()
{
    static MainThreadNeverDestroyed<AtomString> name { "orientation"_s };
    return name;
}

}

OptionSet<Axis> requiredAxesForFeature(const AtomString& featureName)
{
    if (featureName == FeatureNames::width())
        return { Axis::Width };
    if (featureName == FeatureNames::height())
        return { Axis::Height };
    if (featureName == FeatureNames::inlineSize())
        return { Axis::Inline };
    if (featureName == FeatureNames::blockSize())
        return { Axis::Block };
    if (featureName == FeatureNames::aspectRatio() || featureName == FeatureNames::orientation())
        return { Axis::Inline, Axis::Block };
    return { };
}

void serialize(StringBuilder&, const SizeFeature&);
template<typename ConditionType> void serialize(StringBuilder&, const ConditionType&);

static void serialize(StringBuilder& builder, const ContainerQuery& containerQuery)
{
    WTF::switchOn(containerQuery, [&](auto& node) {
        builder.append('(');
        serialize(builder, node);
        builder.append(')');
    }, [&](const CQ::UnknownQuery& unknownQuery) {
        builder.append(unknownQuery.name);
        builder.append('(');
        builder.append(unknownQuery.text);
        builder.append(')');
    });
}

void serialize(StringBuilder& builder, const SizeFeature& sizeFeature)
{
    auto serializeRangeComparisonOperator = [&](ComparisonOperator op) {
        builder.append(' ');
        switch (op) {
        case ComparisonOperator::LessThan:
            builder.append('<');
            break;
        case ComparisonOperator::LessThanOrEqual:
            builder.append("<=");
            break;
        case ComparisonOperator::Equal:
            builder.append('=');
            break;
        case ComparisonOperator::GreaterThan:
            builder.append('>');
            break;
        case ComparisonOperator::GreaterThanOrEqual:
            builder.append(">=");
            break;
        }
        builder.append(' ');
    };

    switch (sizeFeature.syntax) {
    case Syntax::Boolean:
        serializeIdentifier(sizeFeature.name, builder);
        break;

    case Syntax::Colon:
        switch (sizeFeature.rightComparison->op) {
        case ComparisonOperator::LessThanOrEqual:
            builder.append("max-");
            break;
        case ComparisonOperator::Equal:
            break;
        case ComparisonOperator::GreaterThanOrEqual:
            builder.append("min-");
            break;
        case ComparisonOperator::LessThan:
        case ComparisonOperator::GreaterThan:
            ASSERT_NOT_REACHED();
            break;
        }
        serializeIdentifier(sizeFeature.name, builder);

        builder.append(": ");
        builder.append(sizeFeature.rightComparison->value->cssText());
        break;

    case Syntax::Range:
        if (sizeFeature.leftComparison) {
            builder.append(sizeFeature.leftComparison->value->cssText());
            serializeRangeComparisonOperator(sizeFeature.leftComparison->op);
        }

        serializeIdentifier(sizeFeature.name, builder);

        if (sizeFeature.rightComparison) {
            serializeRangeComparisonOperator(sizeFeature.rightComparison->op);
            builder.append(sizeFeature.rightComparison->value->cssText());
        }
        break;
    }
}

template<typename ConditionType>
void serialize(StringBuilder& builder, const ConditionType& condition)
{
    if (condition.queries.size() == 1 && condition.logicalOperator == LogicalOperator::Not) {
        builder.append("not ");
        serialize(builder, condition.queries.first());
        return;
    }

    for (auto& query : condition.queries) {
        if (&query != &condition.queries.first())
            builder.append(condition.logicalOperator == LogicalOperator::And ? " and " : " or ");
        serialize(builder, query);
    }
}

}

void serialize(StringBuilder& builder, const ContainerQuery& query)
{
    CQ::serialize(builder, query);
}

}

