/*
 * Copyright (C) 2020 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. AND ITS 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 APPLE INC. OR ITS 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 "CDMPrivate.h"

#if ENABLE(ENCRYPTED_MEDIA)

#include "CDMKeySystemConfiguration.h"
#include "CDMMediaCapability.h"
#include "CDMRequirement.h"
#include "CDMRestrictions.h"
#include "MediaPlayer.h"
#include "NotImplemented.h"
#include "ParsedContentType.h"
#include "SharedBuffer.h"
#include <wtf/WeakPtr.h>

namespace WebCore {

CDMPrivate::CDMPrivate() = default;
CDMPrivate::~CDMPrivate() = default;

void CDMPrivate::getSupportedConfiguration(CDMKeySystemConfiguration&& candidateConfiguration, LocalStorageAccess access, SupportedConfigurationCallback&& callback)
{
    // https://w3c.github.io/encrypted-media/#get-supported-configuration
    // W3C Editor's Draft 09 November 2016

    // 3.1.1.1 Get Supported Configuration
    // Given a Key Systems implementation implementation, CDMKeySystemConfiguration candidate configuration, and origin,
    // this algorithm returns a supported configuration or NotSupported as appropriate.

    // 1. Let supported configuration be ConsentDenied.
    // 2. Initialize restrictions to indicate that no configurations have had user consent denied.
    CDMRestrictions restrictions { };
    doSupportedConfigurationStep(WTFMove(candidateConfiguration), WTFMove(restrictions), access, WTFMove(callback));
}

void CDMPrivate::doSupportedConfigurationStep(CDMKeySystemConfiguration&& candidateConfiguration, CDMRestrictions&& restrictions, LocalStorageAccess access, SupportedConfigurationCallback&& callback)
{
    // https://w3c.github.io/encrypted-media/#get-supported-configuration
    // W3C Editor's Draft 09 November 2016, ctd.

    // 3.1.1.1 Get Supported Configuration
    // 3. Repeat the following step while supported configuration is ConsentDenied:
    // 3.1. Let supported configuration and, if provided, restrictions be the result of executing the
    // Get Supported Configuration and Consent algorithm with implementation, candidate configuration,
    // restrictions and origin.
    auto optionalConfiguration = getSupportedConfiguration(candidateConfiguration, restrictions, access);
    if (!optionalConfiguration) {
        callback(std::nullopt);
        return;
    }

    auto consentCallback = [weakThis = WeakPtr { *this }, callback = WTFMove(callback), access] (ConsentStatus status, CDMKeySystemConfiguration&& configuration, CDMRestrictions&& restrictions) mutable {
        if (!weakThis) {
            callback(std::nullopt);
            return;
        }
        // 3.1.1.2 Get Supported Configuration and Consent, ctd.
        // 22. Let consent status and updated restrictions be the result of running the Get Consent Status algorithm on accumulated configuration,
        //     restrictions and origin and follow the steps for the value of consent status from the following list:
        switch (status) {
        case ConsentStatus::ConsentDenied:
            // ↳ ConsentDenied:
            //    Return ConsentDenied and updated restrictions.
            weakThis->doSupportedConfigurationStep(WTFMove(configuration), WTFMove(restrictions), access, WTFMove(callback));
            return;

        case ConsentStatus::InformUser:
            // ↳ InformUser
            //    Inform the user that accumulated configuration is in use in the origin including, specifically, the information that
            //    Distinctive Identifier(s) and/or Distinctive Permanent Identifier(s) as appropriate will be used if the
            //    distinctiveIdentifier member of accumulated configuration is "required". Continue to the next step.
            // NOTE: Implement.
            break;

        case ConsentStatus::Allowed:
            // ↳ Allowed:
            // Continue to the next step.
            break;
        }
        // 23. Return accumulated configuration.
        callback(WTFMove(configuration));
    };
    getConsentStatus(WTFMove(optionalConfiguration.value()), WTFMove(restrictions), access, WTFMove(consentCallback));
}

bool CDMPrivate::isPersistentType(CDMSessionType sessionType)
{
    // https://w3c.github.io/encrypted-media/#is-persistent-session-type
    // W3C Editor's Draft 09 November 2016

    // 5.1.1. Is persistent session type?
    // 1. Let the session type be the specified CDMSessionType value.
    // 2. Follow the steps for the value of session type from the following list:
    switch (sessionType) {
    case CDMSessionType::Temporary:
        // ↳ "temporary"
        return false;
    case CDMSessionType::PersistentLicense:
    case CDMSessionType::PersistentUsageRecord:
        // ↳ "persistent-license"
        return true;
    }

    ASSERT_NOT_REACHED();
    return false;
}

std::optional<CDMKeySystemConfiguration> CDMPrivate::getSupportedConfiguration(const CDMKeySystemConfiguration& candidateConfiguration, CDMRestrictions& restrictions, LocalStorageAccess access)
{
    // https://w3c.github.io/encrypted-media/#get-supported-configuration-and-consent
    // W3C Editor's Draft 09 November 2016

    // 3.1.1.2 Get Supported Configuration and Consent
    // Given a Key Systems implementation implementation, CDMKeySystemConfiguration candidate configuration,
    // restrictions and origin, this algorithm returns a supported configuration, NotSupported, or ConsentDenied
    // as appropriate and, in the ConsentDenied case, restrictions.

    // 1. Let accumulated configuration be a new CDMKeySystemConfiguration dictionary.
    CDMKeySystemConfiguration accumulatedConfiguration { };

    // 2. Set the label member of accumulated configuration to equal the label member of candidate configuration.
    accumulatedConfiguration.label = candidateConfiguration.label;

    // 3. If the initDataTypes member of candidate configuration is non-empty, run the following steps:
    if (!candidateConfiguration.initDataTypes.isEmpty()) {
        // 3.1. Let supported types be an empty sequence of DOMStrings.
        Vector<AtomString> supportedTypes;

        // 3.2. For each value in candidate configuration's initDataTypes member:
        for (auto initDataType : candidateConfiguration.initDataTypes) {
            // 3.2.1. Let initDataType be the value.
            // 3.2.2. If the implementation supports generating requests based on initDataType, add initDataType
            //        to supported types. String comparison is case-sensitive. The empty string is never supported.
            if (initDataType.isEmpty())
                continue;

            if (supportedInitDataTypes().contains(initDataType))
                supportedTypes.append(initDataType);
        }

        // 3.3. If supported types is empty, return NotSupported.
        if (supportedTypes.isEmpty())
            return std::nullopt;

        // 3.4. Set the initDataTypes member of accumulated configuration to supported types.
        accumulatedConfiguration.initDataTypes = WTFMove(supportedTypes);
    }

    // 4. Let distinctive identifier requirement be the value of candidate configuration's distinctiveIdentifier member.
    CDMRequirement distinctiveIdentifierRequirement = candidateConfiguration.distinctiveIdentifier;

    // 5. If distinctive identifier requirement is "optional" and Distinctive Identifiers are not allowed according to
    //    restrictions, set distinctive identifier requirement to "not-allowed".
    if (distinctiveIdentifierRequirement == CDMRequirement::Optional && restrictions.distinctiveIdentifierDenied)
        distinctiveIdentifierRequirement = CDMRequirement::NotAllowed;

    // 6. Follow the steps for distinctive identifier requirement from the following list:
    switch (distinctiveIdentifierRequirement) {
    case CDMRequirement::Required:
        // ↳ "required"
        // If the implementation does not support use of Distinctive Identifier(s) in combination
        // with accumulated configuration and restrictions, return NotSupported.
        if (distinctiveIdentifiersRequirement(accumulatedConfiguration, restrictions) == CDMRequirement::NotAllowed)
            return std::nullopt;
        break;

    case CDMRequirement::Optional:
        // ↳ "optional"
        // Continue with the following steps.
        break;

    case CDMRequirement::NotAllowed:
        // ↳ "not-allowed"
        // If the implementation requires use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)
        // in combination with accumulated configuration and restrictions, return NotSupported.
        if (distinctiveIdentifiersRequirement(accumulatedConfiguration, restrictions) == CDMRequirement::Required)
            return std::nullopt;
        break;
    }

    // 7. Set the distinctiveIdentifier member of accumulated configuration to equal distinctive identifier requirement.
    accumulatedConfiguration.distinctiveIdentifier = distinctiveIdentifierRequirement;

    // 8. Let persistent state requirement be equal to the value of candidate configuration's persistentState member.
    CDMRequirement persistentStateRequirement = candidateConfiguration.persistentState;

    // 9. If persistent state requirement is "optional" and persisting state is not allowed according to restrictions,
    //    set persistent state requirement to "not-allowed".
    if (persistentStateRequirement == CDMRequirement::Optional && restrictions.persistentStateDenied)
        persistentStateRequirement = CDMRequirement::NotAllowed;

    // 10. Follow the steps for persistent state requirement from the following list:
    switch (persistentStateRequirement) {
    case CDMRequirement::Required:
        // ↳ "required"
        // If the implementation does not support persisting state in combination with accumulated configuration
        // and restrictions, return NotSupported.
        if (this->persistentStateRequirement(accumulatedConfiguration, restrictions) == CDMRequirement::NotAllowed)
            return std::nullopt;
        break;

    case CDMRequirement::Optional:
        // ↳ "optional"
        // Continue with the following steps.
        break;

    case CDMRequirement::NotAllowed:
        // ↳ "not-allowed"
        // If the implementation requires persisting state in combination with accumulated configuration
        // and restrictions, return NotSupported
        if (this->persistentStateRequirement(accumulatedConfiguration, restrictions) == CDMRequirement::Required)
            return std::nullopt;
        break;
    }

    // 11. Set the persistentState member of accumulated configuration to equal the value of persistent state requirement.
    accumulatedConfiguration.persistentState = persistentStateRequirement;

    // 12. Follow the steps for the first matching condition from the following list:
    Vector<CDMSessionType> sessionTypes;

    if (!candidateConfiguration.sessionTypes.isEmpty()) {
        // ↳ If the sessionTypes member is present [WebIDL] in candidate configuration
        // Let session types be candidate configuration's sessionTypes member.
        sessionTypes = candidateConfiguration.sessionTypes;
    } else {
        // ↳ Otherwise
        // Let session types be [ "temporary" ].
        sessionTypes = { CDMSessionType::Temporary };
    }

    // 13. For each value in session types:
    for (auto& sessionType : sessionTypes) {
        // 13.1. Let session type be the value.
        // 13.2. If accumulated configuration's persistentState value is "not-allowed" and the
        //       Is persistent session type? algorithm returns true for session type return NotSupported.
        if (accumulatedConfiguration.persistentState == CDMRequirement::NotAllowed && isPersistentType(sessionType))
            return std::nullopt;

        // 13.3. If the implementation does not support session type in combination with accumulated configuration
        //       and restrictions for other reasons, return NotSupported.
        if (!supportsSessionTypeWithConfiguration(sessionType, accumulatedConfiguration))
            return std::nullopt;

        // 13.4 If accumulated configuration's persistentState value is "optional" and the result of running the Is
        //      persistent session type? algorithm on session type is true, change accumulated configuration's persistentState
        //      value to "required".
        if (accumulatedConfiguration.persistentState == CDMRequirement::Optional && isPersistentType(sessionType))
            accumulatedConfiguration.persistentState = CDMRequirement::Required;
    }

    // 14. Set the sessionTypes member of accumulated configuration to session types.
    accumulatedConfiguration.sessionTypes = sessionTypes;

    // 15. If the videoCapabilities and audioCapabilities members in candidate configuration are both empty, return NotSupported.
    if (candidateConfiguration.videoCapabilities.isEmpty() && candidateConfiguration.audioCapabilities.isEmpty())
        return std::nullopt;

    // 16. ↳ If the videoCapabilities member in candidate configuration is non-empty:
    if (!candidateConfiguration.videoCapabilities.isEmpty()) {
        // 16.1. Let video capabilities be the result of executing the Get Supported Capabilities for Audio/Video Type algorithm on
        //       Video, candidate configuration's videoCapabilities member, accumulated configuration, and restrictions.
        auto videoCapabilities = getSupportedCapabilitiesForAudioVideoType(AudioVideoType::Video, candidateConfiguration.videoCapabilities, accumulatedConfiguration, restrictions);

        // 16.2. If video capabilities is null, return NotSupported.
        if (!videoCapabilities)
            return std::nullopt;

        // 16.3 Set the videoCapabilities member of accumulated configuration to video capabilities.
        accumulatedConfiguration.videoCapabilities = WTFMove(videoCapabilities.value());
    } else {
        // 16. ↳ Otherwise:
        //     Set the videoCapabilities member of accumulated configuration to an empty sequence.
        accumulatedConfiguration.videoCapabilities = { };
    }

    // 17. ↳ If the audioCapabilities member in candidate configuration is non-empty:
    if (!candidateConfiguration.audioCapabilities.isEmpty()) {
        // 17.1. Let audio capabilities be the result of executing the Get Supported Capabilities for Audio/Video Type algorithm on
        //       Audio, candidate configuration's audioCapabilities member, accumulated configuration, and restrictions.
        auto audioCapabilities = getSupportedCapabilitiesForAudioVideoType(AudioVideoType::Audio, candidateConfiguration.audioCapabilities, accumulatedConfiguration, restrictions);

        // 17.2. If audio capabilities is null, return NotSupported.
        if (!audioCapabilities)
            return std::nullopt;

        // 17.3 Set the audioCapabilities member of accumulated configuration to audio capabilities.
        accumulatedConfiguration.audioCapabilities = WTFMove(audioCapabilities.value());
    } else {
        // 17. ↳ Otherwise:
        //     Set the audioCapabilities member of accumulated configuration to an empty sequence.
        accumulatedConfiguration.audioCapabilities = { };
    }

    // 18. If accumulated configuration's distinctiveIdentifier value is "optional", follow the steps for the first matching
    //     condition from the following list:
    if (accumulatedConfiguration.distinctiveIdentifier == CDMRequirement::Optional) {
        // ↳ If the implementation requires use Distinctive Identifier(s) or Distinctive Permanent Identifier(s) for any of the
        //    combinations in accumulated configuration
        if (distinctiveIdentifiersRequirement(accumulatedConfiguration, restrictions) == CDMRequirement::Required) {
            // Change accumulated configuration's distinctiveIdentifier value to "required".
            accumulatedConfiguration.distinctiveIdentifier = CDMRequirement::Required;
        } else {
            // ↳ Otherwise
            //    Change accumulated configuration's distinctiveIdentifier value to "not-allowed".
            accumulatedConfiguration.distinctiveIdentifier = CDMRequirement::NotAllowed;
        }
    }

    // 19. If accumulated configuration's persistentState value is "optional", follow the steps for the first matching
    //     condition from the following list:
    if (accumulatedConfiguration.persistentState == CDMRequirement::Optional) {
        // ↳ If the implementation requires persisting state for any of the combinations in accumulated configuration
        if (this->persistentStateRequirement(accumulatedConfiguration, restrictions) == CDMRequirement::Required) {
            // Change accumulated configuration's persistentState value to "required".
            accumulatedConfiguration.persistentState = CDMRequirement::Required;
        } else {
            // ↳ Otherwise
            //    Change accumulated configuration's persistentState value to "not-allowed".
            accumulatedConfiguration.persistentState = CDMRequirement::NotAllowed;
        }
    }

    // 20. If implementation in the configuration specified by the combination of the values in accumulated configuration
    //     is not supported or not allowed in the origin, return NotSupported.
    if (!supportsConfiguration(accumulatedConfiguration))
        return std::nullopt;

    if ((accumulatedConfiguration.distinctiveIdentifier == CDMRequirement::Required || accumulatedConfiguration.persistentState == CDMRequirement::Required) && access == LocalStorageAccess::NotAllowed)
        return std::nullopt;

    return accumulatedConfiguration;
    // NOTE: Continued in getConsentStatus().
}

std::optional<Vector<CDMMediaCapability>> CDMPrivate::getSupportedCapabilitiesForAudioVideoType(CDMPrivate::AudioVideoType type, const Vector<CDMMediaCapability>& requestedCapabilities, const CDMKeySystemConfiguration& partialConfiguration, CDMRestrictions& restrictions)
{
    // https://w3c.github.io/encrypted-media/#get-supported-capabilities-for-audio-video-type
    // W3C Editor's Draft 09 November 2016

    // 3.1.1.3 Get Supported Capabilities for Audio/Video Type

    // Given an audio/video type, CDMMediaCapability sequence requested media capabilities, CDMKeySystemConfiguration
    // partial configuration, and restrictions, this algorithm returns a sequence of supported CDMMediaCapability values
    // for this audio/video type or null as appropriate.

    // 1. Let local accumulated configuration be a local copy of partial configuration.
    CDMKeySystemConfiguration accumulatedConfiguration = partialConfiguration;

    // 2. Let supported media capabilities be an empty sequence of CDMMediaCapability dictionaries.
    Vector<CDMMediaCapability> supportedMediaCapabilities { };

    // 3. For each requested media capability in requested media capabilities:
    for (auto& requestedCapability : requestedCapabilities) {
        // 3.1. Let content type be requested media capability's contentType member.
        // 3.2. Let robustness be requested media capability's robustness member.
        String robustness = requestedCapability.robustness;

        // 3.3. If content type is the empty string, return null.
        if (requestedCapability.contentType.isEmpty())
            return std::nullopt;

        // 3.4. If content type is an invalid or unrecognized MIME type, continue to the next iteration.
        std::optional<ParsedContentType> contentType = ParsedContentType::create(requestedCapability.contentType, Mode::Rfc2045);
        if (!contentType)
            continue;

        // 3.5. Let container be the container type specified by content type.
        String container = contentType->mimeType();

        // 3.6. If the user agent does not support container, continue to the next iteration. The case-sensitivity
        //      of string comparisons is determined by the appropriate RFC.
        // 3.7. Let parameters be the RFC 6381 [RFC6381] parameters, if any, specified by content type.
        // 3.8. If the user agent does not recognize one or more parameters, continue to the next iteration.
        // 3.9. Let media types be the set of codecs and codec constraints specified by parameters. The case-sensitivity
        //      of string comparisons is determined by the appropriate RFC or other specification.
        String codecs = contentType->parameterValueForName("codecs"_s);
        if (contentType->parameterCount() > (codecs.isEmpty() ? 0 : 1))
            continue;

        // 3.10. If media types is empty:
        if (codecs.isEmpty()) {
            // ↳ If container normatively implies a specific set of codecs and codec constraints:
            // ↳ Otherwise:
            notImplemented();
        }

        // 3.11. If content type is not strictly a audio/video type, continue to the next iteration.
        // 3.12. If robustness is not the empty string and contains an unrecognized value or a value not supported by
        //       implementation, continue to the next iteration. String comparison is case-sensitive.
        if (!robustness.isEmpty() && !supportedRobustnesses().contains(robustness))
            continue;

        // 3.13. If the user agent and implementation definitely support playback of encrypted media data for the
        //       combination of container, media types, robustness and local accumulated configuration in combination
        //       with restrictions:
        MediaEngineSupportParameters parameters;
        parameters.type = ContentType(contentType->mimeType());
        if (MediaPlayer::supportsType(parameters) == MediaPlayer::SupportsType::IsNotSupported) {

            // Try with Media Source:
            parameters.isMediaSource = true;
            if (MediaPlayer::supportsType(parameters) == MediaPlayer::SupportsType::IsNotSupported)
                continue;
        }

        if (!supportsConfigurationWithRestrictions(accumulatedConfiguration, restrictions))
            continue;

        // 3.13.1. Add requested media capability to supported media capabilities.
        supportedMediaCapabilities.append(requestedCapability);

        // 3.13.2. ↳ If audio/video type is Video:
        //         Add requested media capability to the videoCapabilities member of local accumulated configuration.
        if (type == AudioVideoType::Video)
            accumulatedConfiguration.videoCapabilities.append(requestedCapability);
        // 3.13.2. ↳ If audio/video type is Audio:
        //         Add requested media capability to the audioCapabilities member of local accumulated configuration.
        else
            accumulatedConfiguration.audioCapabilities.append(requestedCapability);
    }

    // 4. If supported media capabilities is empty, return null.
    if (supportedMediaCapabilities.isEmpty())
        return std::nullopt;

    // 5. Return supported media capabilities.
    return supportedMediaCapabilities;
}

void CDMPrivate::getConsentStatus(CDMKeySystemConfiguration&& accumulatedConfiguration, CDMRestrictions&& restrictions, LocalStorageAccess access, ConsentStatusCallback&& callback)
{
    // https://w3c.github.io/encrypted-media/#get-supported-configuration-and-consent
    // W3C Editor's Draft 09 November 2016

    // 3.1.1.2 Get Supported Configuration and Consent, ctd.
    // 21. If accumulated configuration's distinctiveIdentifier value is "required" and the Distinctive Identifier(s) associated
    //     with accumulated configuration are not unique per origin and profile and clearable:
    if (accumulatedConfiguration.distinctiveIdentifier == CDMRequirement::Required && !distinctiveIdentifiersAreUniquePerOriginAndClearable(accumulatedConfiguration)) {
        // 21.1. Update restrictions to reflect that all configurations described by accumulated configuration do not have user consent.
        restrictions.distinctiveIdentifierDenied = true;
        callback(ConsentStatus::ConsentDenied, WTFMove(accumulatedConfiguration), WTFMove(restrictions));
        return;
    }

    // https://w3c.github.io/encrypted-media/#get-consent-status
    // 3.1.1.4 Get Consent Status
    // Given an accumulated configuration, restrictions and origin, this algorithm returns the consent status for accumulated
    // configuration and origin as one of ConsentDenied, InformUser or Allowed, together with an updated value for restrictions
    // in the ConsentDenied case.

    // 1. If there is persisted denial for origin indicating that accumulated configuration is not allowed, run the following steps:
    // 1.1. Update restrictions to reflect the configurations for which consent has been denied.
    // 1.2. Return ConsentDenied and restrictions.
    // 2. If there is persisted consent for origin indicating accumulated configuration is allowed, return Allowed.
    // NOTE: persisted denial / consent unimplemented.

    // 3. If any of the following are true:
    //    ↳ The distinctiveIdentifier member of accumulated configuration is not "not-allowed" and the combination of the User Agent,
    //       implementation and accumulated configuration does not follow all the recommendations of Allow Persistent Data to Be Cleared
    //       with respect to Distinctive Identifier(s).
    // NOTE: assume that implementations follow all recommendations.

    //    ↳ The user agent requires explicit user consent for the accumulated configuration for other reasons.
    // NOTE: assume the user agent does not require explicit user consent.

    // 3.1. Request user consent to use accumulated configuration in the origin and wait for the user response.
    //      The consent must include consent to use a Distinctive Identifier(s) and/or Distinctive Permanent Identifier(s) as appropriate
    //      if accumulated configuration's distinctiveIdentifier member is "required".
    // 3.2. If consent was denied, run the following steps:
    // 3.2.1. Update restrictions to reflect the configurations for which consent was denied.
    // 3.2.1. Return ConsentDenied and restrictions.
    // NOTE: assume implied consent if the combination of origin and topOrigin allows it.
    if (accumulatedConfiguration.distinctiveIdentifier == CDMRequirement::Required && access == LocalStorageAccess::NotAllowed) {
        restrictions.distinctiveIdentifierDenied = true;
        callback(ConsentStatus::ConsentDenied, WTFMove(accumulatedConfiguration), WTFMove(restrictions));
        return;
    }

    // 4. If the distinctiveIdentifier member of accumulated configuration is not "not-allowed", return InformUser.
    if (accumulatedConfiguration.distinctiveIdentifier != CDMRequirement::NotAllowed) {
        callback(ConsentStatus::InformUser, WTFMove(accumulatedConfiguration), WTFMove(restrictions));
        return;
    }

    // 5. If the user agent requires informing the user for the accumulated configuration for other reasons, return InformUser.
    // NOTE: assume the user agent does not require informing the user.

    // 6. Return Allowed.
    callback(ConsentStatus::Allowed, WTFMove(accumulatedConfiguration), WTFMove(restrictions));
}


}

#endif
