/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2016-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.
 * 3. Neither the name of Google Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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
 * OWNER 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.
 */

#pragma once

#if ENABLE(MEDIA_STREAM)

#include "RealtimeMediaSourceSupportedConstraints.h"
#include <cstdlib>
#include <wtf/EnumTraits.h>
#include <wtf/Function.h>
#include <wtf/Vector.h>

namespace WebCore {
    
class MediaConstraint {
public:
    enum class DataType : uint8_t { None, Integer, Double, Boolean, String };

    bool isInt() const { return m_dataType == DataType::Integer; }
    bool isDouble() const { return m_dataType == DataType::Double; }
    bool isBoolean() const { return m_dataType == DataType::Boolean; }
    bool isString() const { return m_dataType == DataType::String; }

    DataType dataType() const { return m_dataType; }
    MediaConstraintType constraintType() const { return m_constraintType; }
    const String& name() const { return m_name; }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        encoder << m_constraintType;
        encoder << m_name;
        encoder << m_dataType;
    }

    template <class Decoder> static WARN_UNUSED_RETURN bool decode(Decoder& decoder, MediaConstraint& constraint)
    {
        if (!decoder.decode(constraint.m_constraintType))
            return false;

        if (!decoder.decode(constraint.m_name))
            return false;

        if (!decoder.decode(constraint.m_dataType))
            return false;

        return true;
    }

    void log() const;

protected:
    MediaConstraint(const String& name, MediaConstraintType constraintType, DataType dataType)
        : m_name(name)
        , m_constraintType(constraintType)
        , m_dataType(dataType)
    {
    }

    MediaConstraint() = default;
    ~MediaConstraint() = default;

private:
    String m_name;
    MediaConstraintType m_constraintType { MediaConstraintType::Unknown };
    DataType m_dataType { DataType::None };
};

template<class ValueType>
class NumericConstraint : public MediaConstraint {
public:
    void setMin(ValueType value) { m_min = value; }
    void setMax(ValueType value) { m_max = value; }
    void setExact(ValueType value) { m_exact = value; }
    void setIdeal(ValueType value) { m_ideal = value; }

    bool getMin(ValueType& min) const
    {
        if (!m_min)
            return false;

        min = m_min.value();
        return true;
    }

    bool getMax(ValueType& max) const
    {
        if (!m_max)
            return false;

        max = m_max.value();
        return true;
    }

    bool getExact(ValueType& exact) const
    {
        if (!m_exact)
            return false;

        exact = m_exact.value();
        return true;
    }

    bool getIdeal(ValueType& ideal) const
    {
        if (!m_ideal)
            return false;

        ideal = m_ideal.value();
        return true;
    }

    bool nearlyEqual(double a, double b) const
    {
        // Don't require strict equality when comparing constraints, or many floating point constraint values,
        // e.g. "aspectRatio: 1.333", will never match.
        const double epsilon = 0.00001;
        return std::abs(a - b) <= epsilon;
    }

    double fitnessDistance(ValueType rangeMin, ValueType rangeMax) const
    {
        // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
        // 1. If the constraint is not supported by the browser, the fitness distance is 0.
        if (isEmpty())
            return 0;

        // 2. If the constraint is required ('min', 'max', or 'exact'), and the settings
        //    dictionary's value for the constraint does not satisfy the constraint, the
        //    fitness distance is positive infinity.
        bool valid = validForRange(rangeMin, rangeMax);
        if (m_exact) {
            if (valid && m_min && m_exact.value() < m_min.value())
                valid = false;
            if (valid && m_max && m_exact.value() > m_max.value())
                valid = false;
            if (!valid)
                return std::numeric_limits<double>::infinity();
        }

        if (m_min) {
            if (valid && m_max && m_min.value() > m_max.value())
                valid = false;
            if (!valid)
                return std::numeric_limits<double>::infinity();
        }

        if (m_max) {
            if (valid && m_min && m_max.value() < m_min.value())
                valid = false;
            if (!valid)
                return std::numeric_limits<double>::infinity();
        }

        // 3. If no ideal value is specified, the fitness distance is 0.
        if (!m_ideal)
            return 0;

        // 4. For all positive numeric non-required constraints (such as height, width, frameRate,
        //    aspectRatio, sampleRate and sampleSize), the fitness distance is the result of the formula
        //
        //         (actual == ideal) ? 0 : |actual - ideal| / max(|actual|,|ideal|)
        ValueType ideal = m_ideal.value();
        if (ideal >= rangeMin && ideal <= rangeMax)
            return 0;

        ideal = ideal > std::max(rangeMin, rangeMax) ? rangeMax : rangeMin;
        return static_cast<double>(std::abs(ideal - m_ideal.value())) / std::max(std::abs(ideal), std::abs(m_ideal.value()));
    }

    double fitnessDistance(const Vector<ValueType>& discreteCapabilityValues) const
    {
        double minDistance = std::numeric_limits<double>::infinity();

        for (auto& value : discreteCapabilityValues) {
            auto distance = fitnessDistance(value, value);
            if (distance < minDistance)
                minDistance = distance;
        }

        return minDistance;
    }

    bool validForRange(ValueType rangeMin, ValueType rangeMax) const
    {
        if (isEmpty())
            return false;

        if (m_exact) {
            const ValueType exact = m_exact.value();
            if (exact < rangeMin && !nearlyEqual(exact, rangeMin))
                return false;
            if (exact > rangeMax && !nearlyEqual(exact, rangeMax))
                return false;
        }

        if (m_min) {
            const ValueType constraintMin = m_min.value();
            if (constraintMin > rangeMax && !nearlyEqual(constraintMin, rangeMax))
                return false;
        }

        if (m_max) {
            const ValueType constraintMax = m_max.value();
            if (constraintMax < rangeMin && !nearlyEqual(constraintMax, rangeMin))
                return false;
        }

        return true;
    }

    ValueType find(const Function<bool(ValueType)>& function) const
    {
        if (m_min && function(m_min.value()))
            return m_min.value();

        if (m_max && function(m_max.value()))
            return m_max.value();

        if (m_exact && function(m_exact.value()))
            return m_exact.value();

        if (m_ideal && function(m_ideal.value()))
            return m_ideal.value();

        return 0;
    }

    ValueType valueForCapabilityRange(ValueType current, ValueType capabilityMin, ValueType capabilityMax) const
    {
        ValueType value { 0 };
        ValueType min { capabilityMin };
        ValueType max { capabilityMax };

        if (m_exact) {
            ASSERT(validForRange(capabilityMin, capabilityMax));
            return m_exact.value();
        }

        if (m_min) {
            value = m_min.value();
            ASSERT(validForRange(value, capabilityMax));
            if (value > min)
                min = value;
            if (value < min)
                value = min;

            // If there is no ideal, don't change if minimum is smaller than current.
            if (!m_ideal && value < current)
                value = current;
        }

        if (m_max) {
            value = m_max.value();
            ASSERT(validForRange(capabilityMin, value));
            if (value < max)
                max = value;
            if (value > max)
                value = max;
        }

        if (m_ideal)
            value = std::max(min, std::min(max, m_ideal.value()));

        return value;
    }

    std::optional<ValueType> valueForDiscreteCapabilityValues(ValueType current, const Vector<ValueType>& discreteCapabilityValues) const
    {
        std::optional<ValueType> value;
        std::optional<ValueType> min;
        std::optional<ValueType> max;

        if (m_exact) {
            ASSERT(discreteCapabilityValues.contains(m_exact.value()));
            return m_exact.value();
        }

        if (m_min) {
            auto index = discreteCapabilityValues.findIf([&](ValueType value) { return m_min.value() >= value; });
            if (index != notFound) {
                min = value = discreteCapabilityValues[index];

                // If there is no ideal, don't change if minimum is smaller than current.
                if (!m_ideal && *value < current)
                    value = current;
            }
        }

        if (m_max && m_max.value() >= discreteCapabilityValues[0]) {
            for (auto& discreteValue : discreteCapabilityValues) {
                if (m_max.value() <= discreteValue)
                    max = value = discreteValue;
            }
        }

        if (m_ideal && discreteCapabilityValues.contains(m_ideal.value())) {
            value = m_ideal.value();
            if (max)
                value = std::min(max.value(), *value);
            if (min)
                value = std::max(min.value(), *value);
        }

        return value;
    }

    bool isEmpty() const { return !m_min && !m_max && !m_exact && !m_ideal; }
    bool isMandatory() const { return m_min || m_max || m_exact; }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        MediaConstraint::encode(encoder);

        encoder << m_min;
        encoder << m_max;
        encoder << m_exact;
        encoder << m_ideal;
    }

    template <class Decoder> static WARN_UNUSED_RETURN bool decode(Decoder& decoder, NumericConstraint& constraint)
    {
        if (!MediaConstraint::decode(decoder, constraint))
            return false;

        if (!decoder.decode(constraint.m_min))
            return false;
        if (!decoder.decode(constraint.m_max))
            return false;
        if (!decoder.decode(constraint.m_exact))
            return false;
        if (!decoder.decode(constraint.m_ideal))
            return false;
    
        return true;
    }

protected:
    NumericConstraint(const String& name, MediaConstraintType type, DataType dataType)
        : MediaConstraint(name, type, dataType)
    {
    }

    NumericConstraint() = default;

    void innerMerge(const NumericConstraint& other)
    {
        if (other.isEmpty())
            return;

        ValueType value;
        if (other.getExact(value))
            m_exact = value;

        if (other.getMin(value))
            m_min = value;

        if (other.getMax(value))
            m_max = value;

        // https://w3c.github.io/mediacapture-main/#constrainable-interface
        // When processing advanced constraints:
        //   ... the User Agent must attempt to apply, individually, any 'ideal' constraints or
        //   a constraint given as a bare value for the property. Of these properties, it must
        //   satisfy the largest number that it can, in any order.
        if (other.getIdeal(value)) {
            if (!m_ideal || value > m_ideal.value())
                m_ideal = value;
        }
    }

    std::optional<ValueType> m_min;
    std::optional<ValueType> m_max;
    std::optional<ValueType> m_exact;
    std::optional<ValueType> m_ideal;
};

class IntConstraint final : public NumericConstraint<int> {
public:
    IntConstraint(const String& name, MediaConstraintType type)
        : NumericConstraint<int>(name, type, DataType::Integer)
    {
    }

    IntConstraint() = default;

    void merge(const MediaConstraint& other)
    {
        ASSERT(other.isInt());
        NumericConstraint::innerMerge(downcast<const IntConstraint>(other));
    }

    void logAsInt() const;
};

class DoubleConstraint final : public NumericConstraint<double> {
public:
    DoubleConstraint(const String& name, MediaConstraintType type)
        : NumericConstraint<double>(name, type, DataType::Double)
    {
    }

    DoubleConstraint() = default;

    void merge(const MediaConstraint& other)
    {
        ASSERT(other.isDouble());
        NumericConstraint::innerMerge(downcast<DoubleConstraint>(other));
    }

    void logAsDouble() const;
};

class BooleanConstraint final : public MediaConstraint {
public:
    BooleanConstraint(const String& name, MediaConstraintType type)
        : MediaConstraint(name, type, DataType::Boolean)
    {
    }

    BooleanConstraint() = default;

    void setExact(bool value) { m_exact = value; }
    void setIdeal(bool value) { m_ideal = value; }

    bool getExact(bool& exact) const
    {
        if (!m_exact)
            return false;

        exact = m_exact.value();
        return true;
    }

    bool getIdeal(bool& ideal) const
    {
        if (!m_ideal)
            return false;

        ideal = m_ideal.value();
        return true;
    }

    double fitnessDistance(bool value) const
    {
        // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
        // 1. If the constraint is not supported by the browser, the fitness distance is 0.
        if (isEmpty())
            return 0;

        // 2. If the constraint is required ('min', 'max', or 'exact'), and the settings
        //    dictionary's value for the constraint does not satisfy the constraint, the
        //    fitness distance is positive infinity.
        if (m_exact && value != m_exact.value())
            return std::numeric_limits<double>::infinity();

        // 3. If no ideal value is specified, the fitness distance is 0.
        if (!m_ideal || m_ideal.value() == value)
            return 0;

        // 5. For all string and enum non-required constraints (deviceId, groupId, facingMode,
        // echoCancellation), the fitness distance is the result of the formula
        //        (actual == ideal) ? 0 : 1
        return 1;
    }

    void merge(const MediaConstraint& other)
    {
        ASSERT(other.isBoolean());
        const BooleanConstraint& typedOther = downcast<BooleanConstraint>(other);

        if (typedOther.isEmpty())
            return;

        bool value;
        if (typedOther.getExact(value))
            m_exact = value;

        if (typedOther.getIdeal(value)) {
            if (!m_ideal || (value && !m_ideal.value()))
                m_ideal = value;
        }
    }

    bool isEmpty() const { return !m_exact && !m_ideal; };
    bool isMandatory() const { return bool(m_exact); }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        MediaConstraint::encode(encoder);
        encoder << m_exact;
        encoder << m_ideal;
    }

    template <class Decoder> static WARN_UNUSED_RETURN bool decode(Decoder& decoder, BooleanConstraint& constraint)
    {
        if (!MediaConstraint::decode(decoder, constraint))
            return false;

        if (!decoder.decode(constraint.m_exact))
            return false;
        if (!decoder.decode(constraint.m_ideal))
            return false;

        return true;
    }

    void logAsBoolean() const;

private:
    std::optional<bool> m_exact;
    std::optional<bool> m_ideal;
};

class StringConstraint : public MediaConstraint {
public:
    StringConstraint(const String& name, MediaConstraintType type)
        : MediaConstraint(name, type, DataType::String)
    {
    }

    StringConstraint() = default;

    void setExact(const String& value)
    {
        m_exact.clear();
        m_exact.append(value);
    }

    void appendExact(const String& value)
    {
        m_exact.append(value);
    }

    void setIdeal(const String& value)
    {
        m_ideal.clear();
        m_ideal.append(value);
    }

    void appendIdeal(const String& value)
    {
        m_ideal.append(value);
    }

    bool getExact(Vector<String>& exact) const
    {
        if (m_exact.isEmpty())
            return false;

        exact = m_exact;
        return true;
    }

    bool getIdeal(Vector<String>& ideal) const
    {
        if (m_ideal.isEmpty())
            return false;

        ideal = m_ideal;
        return true;
    }

    double fitnessDistance(const String&) const;
    double fitnessDistance(const Vector<String>&) const;

    const String& find(const Function<bool(const String&)>&) const;

    bool isEmpty() const { return m_exact.isEmpty() && m_ideal.isEmpty(); }
    bool isMandatory() const { return !m_exact.isEmpty(); }
    WEBCORE_EXPORT void merge(const MediaConstraint&);

    template <class Encoder> void encode(Encoder& encoder) const
    {
        MediaConstraint::encode(encoder);

        encoder << m_exact;
        encoder << m_ideal;
    }

    template <class Decoder> static WARN_UNUSED_RETURN bool decode(Decoder& decoder, StringConstraint& constraint)
    {
        if (!MediaConstraint::decode(decoder, constraint))
            return false;

        if (!decoder.decode(constraint.m_exact))
            return false;
        if (!decoder.decode(constraint.m_ideal))
            return false;

        return true;
    }

    void removeEmptyStringConstraint()
    {
        m_exact.removeAllMatching([](auto& constraint) {
            return constraint.isEmpty();
        });
        m_ideal.removeAllMatching([](auto& constraint) {
            return constraint.isEmpty();
        });
    }

private:
    Vector<String> m_exact;
    Vector<String> m_ideal;
};

class UnknownConstraint final : public MediaConstraint {
public:
    UnknownConstraint(const String& name, MediaConstraintType type)
        : MediaConstraint(name, type, DataType::None)
    {
    }

private:
    bool isEmpty() const { return true; }
    bool isMandatory() const { return false; }
    void merge(const MediaConstraint&) { }
};

class MediaTrackConstraintSetMap {
public:
    WEBCORE_EXPORT void forEach(Function<void(const MediaConstraint&)>&&) const;
    void filter(const Function<bool(const MediaConstraint&)>&) const;
    bool isEmpty() const;
    WEBCORE_EXPORT size_t size() const;

    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<IntConstraint>&&);
    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<DoubleConstraint>&&);
    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<BooleanConstraint>&&);
    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<StringConstraint>&&);

    std::optional<IntConstraint> width() const { return m_width; }
    std::optional<IntConstraint> height() const { return m_height; }
    std::optional<IntConstraint> sampleRate() const { return m_sampleRate; }
    std::optional<IntConstraint> sampleSize() const { return m_sampleSize; }

    std::optional<DoubleConstraint> aspectRatio() const { return m_aspectRatio; }
    std::optional<DoubleConstraint> frameRate() const { return m_frameRate; }
    std::optional<DoubleConstraint> volume() const { return m_volume; }

    std::optional<BooleanConstraint> echoCancellation() const { return m_echoCancellation; }
    std::optional<BooleanConstraint> displaySurface() const { return m_displaySurface; }
    std::optional<BooleanConstraint> logicalSurface() const { return m_logicalSurface; }

    std::optional<StringConstraint> facingMode() const { return m_facingMode; }
    std::optional<StringConstraint> deviceId() const { return m_deviceId; }
    std::optional<StringConstraint> groupId() const { return m_groupId; }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        encoder << m_width;
        encoder << m_height;
        encoder << m_sampleRate;
        encoder << m_sampleSize;

        encoder << m_aspectRatio;
        encoder << m_frameRate;
        encoder << m_volume;

        encoder << m_echoCancellation;
        encoder << m_displaySurface;
        encoder << m_logicalSurface;

        encoder << m_facingMode;
        encoder << m_deviceId;
        encoder << m_groupId;
    }

    template <class Decoder> static std::optional<MediaTrackConstraintSetMap> decode(Decoder& decoder)
    {
        MediaTrackConstraintSetMap map;
        if (!decoder.decode(map.m_width))
            return std::nullopt;
        if (!decoder.decode(map.m_height))
            return std::nullopt;
        if (!decoder.decode(map.m_sampleRate))
            return std::nullopt;
        if (!decoder.decode(map.m_sampleSize))
            return std::nullopt;

        if (!decoder.decode(map.m_aspectRatio))
            return std::nullopt;
        if (!decoder.decode(map.m_frameRate))
            return std::nullopt;
        if (!decoder.decode(map.m_volume))
            return std::nullopt;

        if (!decoder.decode(map.m_echoCancellation))
            return std::nullopt;
        if (!decoder.decode(map.m_displaySurface))
            return std::nullopt;
        if (!decoder.decode(map.m_logicalSurface))
            return std::nullopt;

        if (!decoder.decode(map.m_facingMode))
            return std::nullopt;
        if (!decoder.decode(map.m_deviceId))
            return std::nullopt;
        if (!decoder.decode(map.m_groupId))
            return std::nullopt;

        return map;
    }

private:
    std::optional<IntConstraint> m_width;
    std::optional<IntConstraint> m_height;
    std::optional<IntConstraint> m_sampleRate;
    std::optional<IntConstraint> m_sampleSize;

    std::optional<DoubleConstraint> m_aspectRatio;
    std::optional<DoubleConstraint> m_frameRate;
    std::optional<DoubleConstraint> m_volume;

    std::optional<BooleanConstraint> m_echoCancellation;
    std::optional<BooleanConstraint> m_displaySurface;
    std::optional<BooleanConstraint> m_logicalSurface;

    std::optional<StringConstraint> m_facingMode;
    std::optional<StringConstraint> m_deviceId;
    std::optional<StringConstraint> m_groupId;
};

class FlattenedConstraint {
public:

    void set(const MediaConstraint&);
    void merge(const MediaConstraint&);
    void append(const MediaConstraint&);
    const MediaConstraint* find(MediaConstraintType) const;
    bool isEmpty() const { return m_variants.isEmpty(); }

    class iterator {
    public:
        iterator(const FlattenedConstraint* constraint, size_t index)
            : m_constraint(constraint)
            , m_index(index)
#ifndef NDEBUG
            , m_generation(constraint->m_generation)
#endif
        {
        }

        MediaConstraint& operator*() const
        {
            return m_constraint->m_variants.at(m_index).constraint();
        }

        iterator& operator++()
        {
#ifndef NDEBUG
            ASSERT(m_generation == m_constraint->m_generation);
#endif
            m_index++;
            return *this;
        }

        bool operator==(const iterator& other) const { return m_index == other.m_index; }
        bool operator!=(const iterator& other) const { return !(*this == other); }

    private:
        const FlattenedConstraint* m_constraint { nullptr };
        size_t m_index { 0 };
#ifndef NDEBUG
        int m_generation { 0 };
#endif
    };

    const iterator begin() const { return iterator(this, 0); }
    const iterator end() const { return iterator(this, m_variants.size()); }

private:
    class ConstraintHolder {
    public:
        static ConstraintHolder create(const MediaConstraint& value) { return ConstraintHolder(value); }

        ~ConstraintHolder()
        {
            if (m_value.asRaw) {
                switch (dataType()) {
                case MediaConstraint::DataType::Integer:
                    delete m_value.asInteger;
                    break;
                case MediaConstraint::DataType::Double:
                    delete m_value.asDouble;
                    break;
                case MediaConstraint::DataType::Boolean:
                    delete m_value.asBoolean;
                    break;
                case MediaConstraint::DataType::String:
                    delete m_value.asString;
                    break;
                case MediaConstraint::DataType::None:
                    ASSERT_NOT_REACHED();
                    break;
                }
            }
#ifndef NDEBUG
            m_value.asRaw = reinterpret_cast<MediaConstraint*>(0xbbadbeef);
#endif
        }

        ConstraintHolder(ConstraintHolder&& other)
        {
            switch (other.dataType()) {
            case MediaConstraint::DataType::Integer:
                m_value.asInteger = std::exchange(other.m_value.asInteger, nullptr);
                break;
            case MediaConstraint::DataType::Double:
                m_value.asDouble = std::exchange(other.m_value.asDouble, nullptr);
                break;
            case MediaConstraint::DataType::Boolean:
                m_value.asBoolean = std::exchange(other.m_value.asBoolean, nullptr);
                break;
            case MediaConstraint::DataType::String:
                m_value.asString = std::exchange(other.m_value.asString, nullptr);
                break;
            case MediaConstraint::DataType::None:
                ASSERT_NOT_REACHED();
                break;
            }
        }

        MediaConstraint& constraint() const { return *m_value.asRaw; }
        MediaConstraint::DataType dataType() const { return constraint().dataType(); }
        MediaConstraintType constraintType() const { return constraint().constraintType(); }

    private:
        explicit ConstraintHolder(const MediaConstraint& value)
        {
            switch (value.dataType()) {
            case MediaConstraint::DataType::Integer:
                m_value.asInteger = new IntConstraint(downcast<const IntConstraint>(value));
                break;
            case MediaConstraint::DataType::Double:
                m_value.asDouble = new DoubleConstraint(downcast<DoubleConstraint>(value));
                break;
            case MediaConstraint::DataType::Boolean:
                m_value.asBoolean = new BooleanConstraint(downcast<BooleanConstraint>(value));
                break;
            case MediaConstraint::DataType::String:
                m_value.asString = new StringConstraint(downcast<StringConstraint>(value));
                break;
            case MediaConstraint::DataType::None:
                ASSERT_NOT_REACHED();
                break;
            }
        }
        
        union {
            MediaConstraint* asRaw;
            IntConstraint* asInteger;
            DoubleConstraint* asDouble;
            BooleanConstraint* asBoolean;
            StringConstraint* asString;
        } m_value;
    };

    Vector<ConstraintHolder> m_variants;
#ifndef NDEBUG
    int m_generation { 0 };
#endif
};

struct MediaConstraints {
    void setDefaultVideoConstraints();
    bool isConstraintSet(const Function<bool(const MediaTrackConstraintSetMap&)>&);

    MediaTrackConstraintSetMap mandatoryConstraints;
    Vector<MediaTrackConstraintSetMap> advancedConstraints;
    bool isValid { false };
};
    
} // namespace WebCore

#define SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(ConstraintType, predicate) \
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ConstraintType) \
static bool isType(const WebCore::MediaConstraint& constraint) { return constraint.predicate; } \
SPECIALIZE_TYPE_TRAITS_END()

SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(IntConstraint, isInt())
SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(DoubleConstraint, isDouble())
SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(StringConstraint, isString())
SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(BooleanConstraint, isBoolean())

namespace WTF {

template<> struct EnumTraits<WebCore::MediaConstraint::DataType> {
    using values = EnumValues<
        WebCore::MediaConstraint::DataType,
        WebCore::MediaConstraint::DataType::None,
        WebCore::MediaConstraint::DataType::Integer,
        WebCore::MediaConstraint::DataType::Double,
        WebCore::MediaConstraint::DataType::Boolean,
        WebCore::MediaConstraint::DataType::String
    >;
};

} // namespace WTF

#endif // ENABLE(MEDIA_STREAM)
