/*
 * Copyright (C) 2019 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 THE COPYRIGHT HOLDER “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 THE COPYRIGHT HOLDER 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 "CSSNumericValue.h"

#if ENABLE(CSS_TYPED_OM)

#include "CSSMathInvert.h"
#include "CSSMathMax.h"
#include "CSSMathMin.h"
#include "CSSMathNegate.h"
#include "CSSMathProduct.h"
#include "CSSMathSum.h"
#include "CSSNumericArray.h"
#include "CSSNumericFactory.h"
#include "CSSNumericType.h"
#include "CSSUnitValue.h"
#include "ExceptionOr.h"
#include <wtf/Algorithms.h>
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(CSSNumericValue);

static Ref<CSSNumericValue> negate(Ref<CSSNumericValue>&& value)
{
    // https://drafts.css-houdini.org/css-typed-om/#cssmath-negate-a-cssnumericvalue
    if (auto* mathNegate = dynamicDowncast<CSSMathNegate>(value.get()))
        return mathNegate->value();
    if (auto* unitValue = dynamicDowncast<CSSUnitValue>(value.get()))
        return CSSUnitValue::create(-unitValue->value(), unitValue->unitEnum());
    return CSSMathNegate::create(WTFMove(value));
}

static ExceptionOr<Ref<CSSNumericValue>> invert(Ref<CSSNumericValue>&& value)
{
    // https://drafts.css-houdini.org/css-typed-om/#cssmath-invert-a-cssnumericvalue
    if (auto* mathInvert = dynamicDowncast<CSSMathInvert>(value.get()))
        return Ref { mathInvert->value() };

    if (auto* unitValue = dynamicDowncast<CSSUnitValue>(value.get())) {
        if (unitValue->unitEnum() == CSSUnitType::CSS_NUMBER) {
            if (unitValue->value() == 0.0 || unitValue->value() == -0.0)
                return Exception { RangeError };
            return Ref<CSSNumericValue> { CSSUnitValue::create(1.0 / unitValue->value(), unitValue->unitEnum()) };
        }
    }

    return Ref<CSSNumericValue> { CSSMathInvert::create(WTFMove(value)) };
}

template<typename T>
static RefPtr<CSSNumericValue> operationOnValuesOfSameUnit(T&& operation, const Vector<Ref<CSSNumericValue>>& values)
{
    bool allValuesHaveSameUnit = values.size() && WTF::allOf(values, [&] (const Ref<CSSNumericValue>& value) {
        auto* unitValue = dynamicDowncast<CSSUnitValue>(value.get());
        return unitValue ? unitValue->unitEnum() == downcast<CSSUnitValue>(values[0].get()).unitEnum() : false;
    });
    if (allValuesHaveSameUnit) {
        auto& firstUnitValue = downcast<CSSUnitValue>(values[0].get());
        auto unit = firstUnitValue.unitEnum();
        double result = firstUnitValue.value();
        for (size_t i = 1; i < values.size(); ++i)
            result = operation(result, downcast<CSSUnitValue>(values[i].get()).value());
        return CSSUnitValue::create(result, unit);
    }
    return nullptr;
}

template<typename T> Vector<Ref<CSSNumericValue>> CSSNumericValue::prependItemsOfTypeOrThis(Vector<Ref<CSSNumericValue>>&& numericValues)
{
    Vector<Ref<CSSNumericValue>> values;
    if (T* t = dynamicDowncast<T>(*this))
        values.appendVector(t->values().array());
    else
        values.append(*this);
    values.appendVector(numericValues);
    return values;
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::addInternal(Vector<Ref<CSSNumericValue>>&& numericValues)
{
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-add
    auto values = prependItemsOfTypeOrThis<CSSMathSum>(WTFMove(numericValues));

    if (auto result = operationOnValuesOfSameUnit(std::plus<double>(), values))
        return { *result };

    auto sum = CSSMathSum::create(WTFMove(values));
    if (sum.hasException())
        return sum.releaseException();
    return Ref<CSSNumericValue> { sum.releaseReturnValue() };
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::add(FixedVector<CSSNumberish>&& values)
{
    return addInternal(WTF::map(WTFMove(values), rectifyNumberish));
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::sub(FixedVector<CSSNumberish>&& values)
{
    return addInternal(WTF::map(WTFMove(values), [] (CSSNumberish&& numberish) {
        return negate(rectifyNumberish(WTFMove(numberish)));
    }));
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::multiplyInternal(Vector<Ref<CSSNumericValue>>&& numericValues)
{
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-mul
    auto values = prependItemsOfTypeOrThis<CSSMathProduct>(WTFMove(numericValues));

    bool allUnitValues = WTF::allOf(values, [&] (const Ref<CSSNumericValue>& value) {
        return is<CSSUnitValue>(value.get());
    });
    if (allUnitValues) {
        bool multipleUnitsFound { false };
        std::optional<size_t> nonNumberUnitIndex;
        for (size_t i = 0; i < values.size(); ++i) {
            auto unit = downcast<CSSUnitValue>(values[i].get()).unitEnum();
            if (unit == CSSUnitType::CSS_NUMBER)
                continue;
            if (nonNumberUnitIndex) {
                multipleUnitsFound = true;
                break;
            }
            nonNumberUnitIndex = i;
        }
        if (!multipleUnitsFound) {
            double product = 1;
            for (const Ref<CSSNumericValue>& value : values)
                product *= downcast<CSSUnitValue>(value.get()).value();
            auto unit = nonNumberUnitIndex ? downcast<CSSUnitValue>(values[*nonNumberUnitIndex].get()).unitEnum() : CSSUnitType::CSS_NUMBER;
            return { CSSUnitValue::create(product, unit) };
        }
    }

    auto product = CSSMathProduct::create(WTFMove(values));
    if (product.hasException())
        return product.releaseException();
    return Ref<CSSNumericValue> { product.releaseReturnValue() };
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::mul(FixedVector<CSSNumberish>&& values)
{
    return multiplyInternal(WTF::map(WTFMove(values), rectifyNumberish));
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::div(FixedVector<CSSNumberish>&& values)
{
    Vector<Ref<CSSNumericValue>> invertedValues;
    invertedValues.reserveInitialCapacity(values.size());
    for (auto&& value : WTFMove(values)) {
        auto inverted = invert(rectifyNumberish(WTFMove(value)));
        if (inverted.hasException())
            return inverted.releaseException();
        invertedValues.uncheckedAppend(inverted.releaseReturnValue());
    }
    return multiplyInternal(WTFMove(invertedValues));
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::min(FixedVector<CSSNumberish>&& numberishes)
{
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-min
    auto values = prependItemsOfTypeOrThis<CSSMathMin>(WTF::map(WTFMove(numberishes), rectifyNumberish));
    
    if (auto result = operationOnValuesOfSameUnit<const double&(*)(const double&, const double&)>(std::min<double>, values))
        return { *result };

    auto result = CSSMathMin::create(WTFMove(values));
    if (result.hasException())
        return result.releaseException();
    return { result.releaseReturnValue() };
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::max(FixedVector<CSSNumberish>&& numberishes)
{
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-max
    auto values = prependItemsOfTypeOrThis<CSSMathMax>(WTF::map(WTFMove(numberishes), rectifyNumberish));
    
    if (auto result = operationOnValuesOfSameUnit<const double&(*)(const double&, const double&)>(std::max<double>, values))
        return { *result };

    auto result = CSSMathMax::create(WTFMove(values));
    if (result.hasException())
        return result.releaseException();
    return { result.releaseReturnValue() };
}

Ref<CSSNumericValue> CSSNumericValue::rectifyNumberish(CSSNumberish&& numberish)
{
    // https://drafts.css-houdini.org/css-typed-om/#rectify-a-numberish-value
    return WTF::switchOn(numberish, [](RefPtr<CSSNumericValue>& value) {
        RELEASE_ASSERT(!!value);
        return Ref<CSSNumericValue> { *value };
    }, [](double value) {
        return Ref<CSSNumericValue> { CSSNumericFactory::number(value) };
    });
}

bool CSSNumericValue::equals(FixedVector<CSSNumberish>&& value)
{
    UNUSED_PARAM(value);
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-equals
    // FIXME: add impl.
    return false;
}

ExceptionOr<Ref<CSSUnitValue>> CSSNumericValue::to(String&& unit)
{
    return to(CSSUnitValue::parseUnit(unit));
}

ExceptionOr<Ref<CSSUnitValue>> CSSNumericValue::to(CSSUnitType unit)
{
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-to
    auto type = CSSNumericType::create(unit);
    if (!type)
        return Exception { SyntaxError };

    auto sumValue = toSumValue();
    if (!sumValue || sumValue->size() != 1)
        return Exception { TypeError };

    auto& addend = (*sumValue)[0];
    auto unconverted = [] (const auto& addend) -> RefPtr<CSSUnitValue> {
        switch (addend.units.size()) {
        case 0:
            return CSSUnitValue::create(addend.value, CSSUnitType::CSS_NUMBER);
        case 1:
            return CSSUnitValue::create(addend.value, addend.units.begin()->key);
        default:
            break;
        }
        return nullptr;
    } (addend);
    if (!unconverted)
        return Exception { TypeError };

    auto converted = unconverted->convertTo(unit);
    if (!converted)
        return Exception { TypeError };
    return converted.releaseNonNull();
}

ExceptionOr<Ref<CSSMathSum>> CSSNumericValue::toSum(FixedVector<String>&& units)
{
    UNUSED_PARAM(units);
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-tosum
    // FIXME: add impl.
    return CSSMathSum::create(FixedVector<CSSNumberish> { 1.0 });
}

ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::parse(String&& cssText)
{
    UNUSED_PARAM(cssText);
    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-parse
    // FIXME: add impl.
    return Exception { NotSupportedError, "Not implemented Error"_s };
}

} // namespace WebCore

#endif
