/*
 * Copyright (C) 2016 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.
 */

#include "config.h"
#include "MediaConstraints.h"

#if ENABLE(MEDIA_STREAM)
#include "RealtimeMediaSourceCenter.h"
#include "RealtimeMediaSourceSupportedConstraints.h"
#include <wtf/StdLibExtras.h>

namespace WebCore {

const String& StringConstraint::find(const Function<bool(const String&)>& filter) const
{
    for (auto& constraint : m_exact) {
        if (filter(constraint))
            return constraint;
    }

    for (auto& constraint : m_ideal) {
        if (filter(constraint))
            return constraint;
    }
    
    return emptyString();
}

double StringConstraint::fitnessDistance(const String& 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.isEmpty() && m_exact.find(value) == notFound)
        return std::numeric_limits<double>::infinity();

    // 3. If no ideal value is specified, the fitness distance is 0.
    if (m_ideal.isEmpty())
        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 m_ideal.find(value) != notFound ? 0 : 1;
}

double StringConstraint::fitnessDistance(const Vector<String>& values) const
{
    if (isEmpty())
        return 0;

    double minimumDistance = std::numeric_limits<double>::infinity();
    for (auto& value : values)
        minimumDistance = std::min(minimumDistance, fitnessDistance(value));

    return minimumDistance;
}

void StringConstraint::merge(const MediaConstraint& other)
{
    ASSERT(other.isString());
    const StringConstraint& typedOther = downcast<StringConstraint>(other);

    if (typedOther.isEmpty())
        return;

    Vector<String> values;
    if (typedOther.getExact(values)) {
        if (m_exact.isEmpty())
            m_exact = values;
        else {
            for (auto& value : values) {
                if (m_exact.find(value) == notFound)
                    m_exact.append(value);
            }
        }
    }

    if (typedOther.getIdeal(values)) {
        if (m_ideal.isEmpty())
            m_ideal = values;
        else {
            for (auto& value : values) {
                if (m_ideal.find(value) == notFound)
                    m_ideal.append(value);
            }
        }
    }
}

void FlattenedConstraint::set(const MediaConstraint& constraint)
{
    if (find(constraint.constraintType()))
        return;

    append(constraint);
}

void FlattenedConstraint::merge(const MediaConstraint& constraint)
{
    for (auto& variant : *this) {
        if (variant.constraintType() != constraint.constraintType())
            continue;

        switch (variant.dataType()) {
        case MediaConstraint::DataType::Integer:
            ASSERT(constraint.isInt());
            downcast<const IntConstraint>(variant).merge(downcast<const IntConstraint>(constraint));
            return;
        case MediaConstraint::DataType::Double:
            ASSERT(constraint.isDouble());
            downcast<const DoubleConstraint>(variant).merge(downcast<const DoubleConstraint>(constraint));
            return;
        case MediaConstraint::DataType::Boolean:
            ASSERT(constraint.isBoolean());
            downcast<const BooleanConstraint>(variant).merge(downcast<const BooleanConstraint>(constraint));
            return;
        case MediaConstraint::DataType::String:
            ASSERT(constraint.isString());
            downcast<const StringConstraint>(variant).merge(downcast<const StringConstraint>(constraint));
            return;
        case MediaConstraint::DataType::None:
            ASSERT_NOT_REACHED();
            return;
        }
    }

    append(constraint);
}

void FlattenedConstraint::append(const MediaConstraint& constraint)
{
#ifndef NDEBUG
    ++m_generation;
#endif

    m_variants.append(ConstraintHolder::create(constraint));
}

const MediaConstraint* FlattenedConstraint::find(MediaConstraintType type) const
{
    for (auto& variant : m_variants) {
        if (variant.constraintType() == type)
            return &variant.constraint();
    }

    return nullptr;
}

void MediaTrackConstraintSetMap::forEach(Function<void(const MediaConstraint&)>&& callback) const
{
    filter([callback = WTFMove(callback)] (const MediaConstraint& constraint) mutable {
        callback(constraint);
        return false;
    });
}

void MediaTrackConstraintSetMap::filter(const Function<bool(const MediaConstraint&)>& callback) const
{
    if (m_width && !m_width->isEmpty() && callback(*m_width))
        return;
    if (m_height && !m_height->isEmpty() && callback(*m_height))
        return;
    if (m_sampleRate && !m_sampleRate->isEmpty() && callback(*m_sampleRate))
        return;
    if (m_sampleSize && !m_sampleSize->isEmpty() && callback(*m_sampleSize))
        return;

    if (m_aspectRatio && !m_aspectRatio->isEmpty() && callback(*m_aspectRatio))
        return;
    if (m_frameRate && !m_frameRate->isEmpty() && callback(*m_frameRate))
        return;
    if (m_volume && !m_volume->isEmpty() && callback(*m_volume))
        return;

    if (m_echoCancellation && !m_echoCancellation->isEmpty() && callback(*m_echoCancellation))
        return;

    if (m_facingMode && !m_facingMode->isEmpty() && callback(*m_facingMode))
        return;
    if (m_deviceId && !m_deviceId->isEmpty() && callback(*m_deviceId))
        return;
    if (m_groupId && !m_groupId->isEmpty() && callback(*m_groupId))
        return;
}

void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<IntConstraint>&& constraint)
{
    switch (constraintType) {
    case MediaConstraintType::Width:
        m_width = WTFMove(constraint);
        break;
    case MediaConstraintType::Height:
        m_height = WTFMove(constraint);
        break;
    case MediaConstraintType::SampleRate:
        m_sampleRate = WTFMove(constraint);
        break;
    case MediaConstraintType::SampleSize:
        m_sampleSize = WTFMove(constraint);
        break;

    case MediaConstraintType::AspectRatio:
    case MediaConstraintType::FrameRate:
    case MediaConstraintType::Volume:
    case MediaConstraintType::EchoCancellation:
    case MediaConstraintType::FacingMode:
    case MediaConstraintType::DeviceId:
    case MediaConstraintType::GroupId:
    case MediaConstraintType::DisplaySurface:
    case MediaConstraintType::LogicalSurface:
    case MediaConstraintType::Unknown:
        ASSERT_NOT_REACHED();
        break;
    }
}

void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<DoubleConstraint>&& constraint)
{
    switch (constraintType) {
    case MediaConstraintType::AspectRatio:
        m_aspectRatio = WTFMove(constraint);
        break;
    case MediaConstraintType::FrameRate:
        m_frameRate = WTFMove(constraint);
        break;
    case MediaConstraintType::Volume:
        m_volume = WTFMove(constraint);
        break;

    case MediaConstraintType::Width:
    case MediaConstraintType::Height:
    case MediaConstraintType::SampleRate:
    case MediaConstraintType::SampleSize:
    case MediaConstraintType::EchoCancellation:
    case MediaConstraintType::FacingMode:
    case MediaConstraintType::DeviceId:
    case MediaConstraintType::GroupId:
    case MediaConstraintType::DisplaySurface:
    case MediaConstraintType::LogicalSurface:
    case MediaConstraintType::Unknown:
        ASSERT_NOT_REACHED();
        break;
    }
}

void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<BooleanConstraint>&& constraint)
{
    switch (constraintType) {
    case MediaConstraintType::EchoCancellation:
        m_echoCancellation = WTFMove(constraint);
        break;
    case MediaConstraintType::DisplaySurface:
        m_displaySurface = WTFMove(constraint);
        break;
    case MediaConstraintType::LogicalSurface:
        m_logicalSurface = WTFMove(constraint);
        break;

    case MediaConstraintType::Width:
    case MediaConstraintType::Height:
    case MediaConstraintType::SampleRate:
    case MediaConstraintType::SampleSize:
    case MediaConstraintType::AspectRatio:
    case MediaConstraintType::FrameRate:
    case MediaConstraintType::Volume:
    case MediaConstraintType::FacingMode:
    case MediaConstraintType::DeviceId:
    case MediaConstraintType::GroupId:
    case MediaConstraintType::Unknown:
        ASSERT_NOT_REACHED();
        break;
    }
}

void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<StringConstraint>&& constraint)
{
    switch (constraintType) {
    case MediaConstraintType::FacingMode:
        m_facingMode = WTFMove(constraint);
        break;
    case MediaConstraintType::DeviceId:
        if (constraint)
            constraint->removeEmptyStringConstraint();
        m_deviceId = WTFMove(constraint);
        break;
    case MediaConstraintType::GroupId:
        m_groupId = WTFMove(constraint);
        break;

    case MediaConstraintType::Width:
    case MediaConstraintType::Height:
    case MediaConstraintType::SampleRate:
    case MediaConstraintType::SampleSize:
    case MediaConstraintType::AspectRatio:
    case MediaConstraintType::FrameRate:
    case MediaConstraintType::Volume:
    case MediaConstraintType::EchoCancellation:
    case MediaConstraintType::DisplaySurface:
    case MediaConstraintType::LogicalSurface:
    case MediaConstraintType::Unknown:
        ASSERT_NOT_REACHED();
        break;
    }
}

size_t MediaTrackConstraintSetMap::size() const
{
    size_t count = 0;
    forEach([&count] (const MediaConstraint&) mutable {
        ++count;
    });

    return count;
}

bool MediaTrackConstraintSetMap::isEmpty() const
{
    return !size();
}

static inline void addDefaultVideoConstraints(MediaTrackConstraintSetMap& videoConstraints, bool addFrameRateConstraint, bool addSizeConstraint, bool addFacingModeConstraint)
{
    if (addFrameRateConstraint) {
        DoubleConstraint frameRateConstraint({ }, MediaConstraintType::FrameRate);
        frameRateConstraint.setIdeal(30);
        videoConstraints.set(MediaConstraintType::FrameRate, WTFMove(frameRateConstraint));
    }
    if (addSizeConstraint) {
        IntConstraint widthConstraint({ }, MediaConstraintType::Width);
        widthConstraint.setIdeal(640);
        videoConstraints.set(MediaConstraintType::Width, WTFMove(widthConstraint));
        
        IntConstraint heightConstraint({ }, MediaConstraintType::Height);
        heightConstraint.setIdeal(480);
        videoConstraints.set(MediaConstraintType::Height, WTFMove(heightConstraint));
    }
    if (addFacingModeConstraint) {
        StringConstraint facingModeConstraint({ }, MediaConstraintType::FacingMode);
        facingModeConstraint.setIdeal("user"_s);
        videoConstraints.set(MediaConstraintType::FacingMode, WTFMove(facingModeConstraint));
    }
}

bool MediaConstraints::isConstraintSet(const Function<bool(const MediaTrackConstraintSetMap&)>& callback)
{
    if (callback(mandatoryConstraints))
        return true;
    
    for (const auto& constraint : advancedConstraints) {
        if (callback(constraint))
            return true;
    }
    return false;
}

void MediaConstraints::setDefaultVideoConstraints()
{
    // 640x480, 30fps, front-facing camera
    bool needsFrameRateConstraints = !isConstraintSet([](const MediaTrackConstraintSetMap& constraint) {
        return !!constraint.frameRate() || !!constraint.width() || !!constraint.height();
    });
    
    bool needsSizeConstraints = !isConstraintSet([](const MediaTrackConstraintSetMap& constraint) {
        return !!constraint.width() || !!constraint.height();
    });
    
    bool needsFacingModeConstraints = !isConstraintSet([](const MediaTrackConstraintSetMap& constraint) {
        return !!constraint.facingMode() || !!constraint.deviceId();
    });
    
    addDefaultVideoConstraints(mandatoryConstraints, needsFrameRateConstraints, needsSizeConstraints, needsFacingModeConstraints);
}

void MediaConstraint::log() const
{
    switch (dataType()) {
    case DataType::Boolean:
        downcast<const BooleanConstraint>(*this).logAsBoolean();
        break;
    case DataType::Double:
        downcast<const DoubleConstraint>(*this).logAsDouble();
        break;
    case DataType::Integer:
        downcast<const IntConstraint>(*this).logAsInt();
        break;
    case DataType::None:
    case DataType::String:
        WTFLogAlways("MediaConstraint %d of type %d", static_cast<int>(constraintType()), static_cast<int>(dataType()));
    }
}

void BooleanConstraint::logAsBoolean() const
{
    WTFLogAlways("BooleanConstraint %d, exact %d, ideal %d", static_cast<int>(constraintType()), m_exact ? *m_exact : -1, m_ideal ? *m_ideal : -1);
}

void DoubleConstraint::logAsDouble() const
{
    WTFLogAlways("DoubleConstraint %d, min %f, max %f, exact %f, ideal %f", static_cast<int>(constraintType()), m_min ? *m_min : -1, m_max ? *m_max : -1, m_exact ? *m_exact : -1, m_ideal ? *m_ideal : -1);
}

void IntConstraint::logAsInt() const
{
    WTFLogAlways("IntConstraint %d, min %d, max %d, exact %d, ideal %d", static_cast<int>(constraintType()), m_min ? *m_min : -1, m_max ? *m_max : -1, m_exact ? *m_exact : -1, m_ideal ? *m_ideal : -1);
}


}

#endif // ENABLE(MEDIA_STREAM)
