/*
 * Copyright (C) 2016 Metrological Group B.V.
 * Copyright (C) 2016 Igalia S.L.
 *
 * 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 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
 * HOLDER 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 "MediaKeySession.h"

#if ENABLE(ENCRYPTED_MEDIA)

#include "CDM.h"
#include "CDMInstance.h"
#include "DOMPromiseProxy.h"
#include "Document.h"
#include "EventLoop.h"
#include "EventNames.h"
#include "Logging.h"
#include "MediaKeyMessageEvent.h"
#include "MediaKeyMessageEventInit.h"
#include "MediaKeyMessageType.h"
#include "MediaKeyStatusMap.h"
#include "MediaKeys.h"
#include "NotImplemented.h"
#include "Page.h"
#include "SecurityOrigin.h"
#include "SecurityOriginData.h"
#include "Settings.h"
#include "SharedBuffer.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/LoggerHelper.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(MediaKeySession);

Ref<MediaKeySession> MediaKeySession::create(Document& document, WeakPtr<MediaKeys>&& keys, MediaKeySessionType sessionType, bool useDistinctiveIdentifier, Ref<CDM>&& implementation, Ref<CDMInstanceSession>&& instanceSession)
{
    auto session = adoptRef(*new MediaKeySession(document, WTFMove(keys), sessionType, useDistinctiveIdentifier, WTFMove(implementation), WTFMove(instanceSession)));
    session->suspendIfNeeded();
    return session;
}

MediaKeySession::MediaKeySession(Document& document, WeakPtr<MediaKeys>&& keys, MediaKeySessionType sessionType, bool useDistinctiveIdentifier, Ref<CDM>&& implementation, Ref<CDMInstanceSession>&& instanceSession)
    : ActiveDOMObject(&document)
#if !RELEASE_LOG_DISABLED
    , m_logger(document.logger())
    , m_logIdentifier(keys ? keys->nextChildIdentifier() : nullptr)
#endif
    , m_keys(WTFMove(keys))
    , m_expiration(std::numeric_limits<double>::quiet_NaN())
    , m_closedPromise(makeUniqueRef<ClosedPromise>())
    , m_keyStatuses(MediaKeyStatusMap::create(*this))
    , m_useDistinctiveIdentifier(useDistinctiveIdentifier)
    , m_sessionType(sessionType)
    , m_implementation(WTFMove(implementation))
    , m_instanceSession(WTFMove(instanceSession))
    , m_displayChangedObserver([this] (auto displayID) { displayChanged(displayID); })
{
    // https://w3c.github.io/encrypted-media/#dom-mediakeys-createsession
    // W3C Editor's Draft 09 November 2016
    // createSession(), ctd.

    INFO_LOG(LOGIDENTIFIER, "sessionType(", sessionType, "), useDistinctiveIdentifier(", useDistinctiveIdentifier, ")");

    // 3.1. Let the sessionId attribute be the empty string.
    // 3.2. Let the expiration attribute be NaN.
    // 3.3. Let the closed attribute be a new promise.
    // 3.4. Let key status be a new empty MediaKeyStatusMap object, and initialize it as follows:
    // 3.4.1. Let the size attribute be 0.
    // 3.5. Let the session type value be sessionType.
    // 3.6. Let the uninitialized value be true.
    // 3.7. Let the callable value be false.
    // 3.8. Let the use distinctive identifier value be this object's use distinctive identifier value.
    // 3.9. Let the cdm implementation value be this object's cdm implementation.
    // 3.10. Let the cdm instance value be this object's cdm instance.

    UNUSED_PARAM(m_callable);
    UNUSED_PARAM(m_sessionType);
    UNUSED_PARAM(m_useDistinctiveIdentifier);
    UNUSED_PARAM(m_closed);
    UNUSED_PARAM(m_uninitialized);

#if !RELEASE_LOG_DISABLED
    m_instanceSession->setLogger(m_logger, m_logIdentifier);
#endif
    m_instanceSession->setClient(*this);

    document.addDisplayChangedObserver(m_displayChangedObserver);
}

MediaKeySession::~MediaKeySession()
{
    m_keyStatuses->detachSession();
    m_instanceSession->clearClient();
}

const String& MediaKeySession::sessionId() const
{
    return m_sessionId;
}

double MediaKeySession::expiration() const
{
    return m_expiration;
}

Ref<MediaKeyStatusMap> MediaKeySession::keyStatuses() const
{
    return m_keyStatuses.copyRef();
}

void MediaKeySession::generateRequest(const AtomString& initDataType, const BufferSource& initData, Ref<DeferredPromise>&& promise)
{
    // https://w3c.github.io/encrypted-media/#dom-mediakeysession-generaterequest
    // W3C Editor's Draft 09 November 2016

    // When this method is invoked, the user agent must run the following steps:
    // 1. If this object is closed, return a promise rejected with an InvalidStateError.
    // 2. If this object's uninitialized value is false, return a promise rejected with an InvalidStateError.
    auto identifier = LOGIDENTIFIER;
    INFO_LOG(identifier, "initDataType(", initDataType, "), initData.length(", initData.length(), ")");

    if (m_closed || !m_uninitialized) {
        INFO_LOG(identifier, "Rejected: closed(", m_closed, ") or !uninitialized(", !m_uninitialized, ")");
        promise->reject(InvalidStateError);
        return;
    }

    // 3. Let this object's uninitialized value be false.
    m_uninitialized = false;

    // 4. If initDataType is the empty string, return a promise rejected with a newly created TypeError.
    // 5. If initData is an empty array, return a promise rejected with a newly created TypeError.
    if (initDataType.isEmpty() || !initData.length()) {
        INFO_LOG(identifier, "Rejected: initDataType empty(", initDataType.isEmpty(), ") or initData empty(", !initData.length(), ")");
        promise->reject(TypeError);
        return;
    }

    // 6. If the Key System implementation represented by this object's cdm implementation value does not support
    //    initDataType as an Initialization Data Type, return a promise rejected with a NotSupportedError. String
    //    comparison is case-sensitive.
    if (!m_implementation->supportsInitDataType(initDataType)) {
        INFO_LOG(identifier, "Rejected: initDataType(", initDataType, ") unsupported");
        promise->reject(NotSupportedError);
        return;
    }

    // 7. Let init data be a copy of the contents of the initData parameter.
    // 8. Let session type be this object's session type.
    // 9. Let promise be a new promise.
    // 10. Run the following steps in parallel:
    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, weakThis = WeakPtr { *this }, initData = SharedBuffer::create(initData.data(), initData.length()), initDataType, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
        // 10.1. If the init data is not valid for initDataType, reject promise with a newly created TypeError.
        // 10.2. Let sanitized init data be a validated and sanitized version of init data.
        RefPtr<FragmentedSharedBuffer> sanitizedInitData = m_implementation->sanitizeInitData(initDataType, initData);

        // 10.3. If the preceding step failed, reject promise with a newly created TypeError.
        if (!sanitizedInitData) {
            INFO_LOG(identifier, "::task() Rejected: cannot sanitize init data");
            promise->reject(TypeError);
            return;
        }

        // 10.4. If sanitized init data is empty, reject promise with a NotSupportedError.
        if (sanitizedInitData->isEmpty()) {
            INFO_LOG(identifier, "::task() Rejected: empty sanitized init data");
            promise->reject(NotSupportedError);
            return;
        }

        // 10.5. Let session id be the empty string.
        // 10.6. Let message be null.
        // 10.7. Let message type be null.
        // 10.8. Let cdm be the CDM instance represented by this object's cdm instance value.
        // 10.9. Use the cdm to execute the following steps:
        // 10.9.1. If the sanitized init data is not supported by the cdm, reject promise with a NotSupportedError.
        if (!m_implementation->supportsInitData(initDataType, *sanitizedInitData)) {
            INFO_LOG(identifier, "::task() Rejected: unsupported initDataType (", initDataType, ") or sanitized initData");
            promise->reject(NotSupportedError);
            return;
        }

        // 10.9.2 Follow the steps for the value of session type from the following list:
        //   ↳ "temporary"
        //     Let requested license type be a temporary non-persistable license.
        //   ↳ "persistent-license"
        //     Let requested license type be a persistable license.
        //   ↳ "persistent-usage-record"
        //     1. Initialize this object's record of key usage as follows.
        //        Set the list of key IDs known to the session to an empty list.
        //        Set the first decrypt time to null.
        //        Set the latest decrypt time to null.
        //     2. Let requested license type be a non-persistable license that will
        //        persist a record of key usage.

        if (m_sessionType == MediaKeySessionType::PersistentUsageRecord) {
            m_recordOfKeyUsage.clear();
            m_firstDecryptTime = 0;
            m_latestDecryptTime = 0;
        }

        m_instanceSession->requestLicense(m_sessionType, initDataType, sanitizedInitData.releaseNonNull(), [this, weakThis, promise = WTFMove(promise), identifier = WTFMove(identifier)] (Ref<FragmentedSharedBuffer>&& message, const String& sessionId, bool needsIndividualization, CDMInstanceSession::SuccessValue succeeded) mutable {
            if (!weakThis)
                return;

            // 10.9.3. Let session id be a unique Session ID string.

            MediaKeyMessageType messageType;
            if (!needsIndividualization) {
                // 10.9.4. If a license request for the requested license type can be generated based on the sanitized init data:
                // 10.9.4.1. Let message be a license request for the requested license type generated based on the sanitized init data interpreted per initDataType.
                // 10.9.4.2. Let message type be "license-request".
                messageType = MediaKeyMessageType::LicenseRequest;
            } else {
                // 10.9.5. Otherwise:
                // 10.9.5.1. Let message be the request that needs to be processed before a license request request for the requested license
                //           type can be generated based on the sanitized init data.
                // 10.9.5.2. Let message type reflect the type of message, either "license-request" or "individualization-request".
                messageType = MediaKeyMessageType::IndividualizationRequest;
            }

            // 10.10. Queue a task to run the following steps:
            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, promise = WTFMove(promise), message = WTFMove(message), messageType, sessionId, succeeded, identifier = WTFMove(identifier)] () mutable {
                // 10.10.1. If any of the preceding steps failed, reject promise with a new DOMException whose name is the appropriate error name.
                if (succeeded == CDMInstanceSession::SuccessValue::Failed) {
                    INFO_LOG(identifier, "::task() Rejected: failed to request license");
                    promise->reject(NotSupportedError);
                    return;
                }
                // 10.10.2. Set the sessionId attribute to session id.
                m_sessionId = sessionId;

                // 10.9.3. Let this object's callable value be true.
                m_callable = true;

                // 10.9.3. Run the Queue a "message" Event algorithm on the session, providing message type and message.
                enqueueMessage(messageType, message);

                // 10.9.3. Resolve promise.
                INFO_LOG(identifier, "::task() Resolved");
                promise->resolve();
            });
        });
    });

    // 11. Return promise.
}

void MediaKeySession::load(const String& sessionId, Ref<DeferredPromise>&& promise)
{
    // https://w3c.github.io/encrypted-media/#dom-mediakeysession-load
    // W3C Editor's Draft 09 November 2016

    auto identifier = LOGIDENTIFIER;
    INFO_LOG(identifier, "sessionId(", sessionId, ")");

    // 1. If this object is closed, return a promise rejected with an InvalidStateError.
    // 2. If this object's uninitialized value is false, return a promise rejected with an InvalidStateError.
    if (m_closed || !m_uninitialized) {
        INFO_LOG(identifier, "Rejected: closed(", m_closed, ") or !uninitialized(", !m_uninitialized, ")");
        promise->reject(InvalidStateError);
        return;
    }

    // 3. Let this object's uninitialized value be false.
    m_uninitialized = false;

    // 4. If sessionId is the empty string, return a promise rejected with a newly created TypeError.
    // 5. If the result of running the Is persistent session type? algorithm on this object's session type is false, return a promise rejected with a newly created TypeError.
    if (sessionId.isEmpty() || m_sessionType == MediaKeySessionType::Temporary) {
        INFO_LOG(identifier, "Rejected: sessionID empty(", sessionId.isEmpty(), ") or sessionType == Temporary (", m_sessionType == MediaKeySessionType::Temporary, ")");
        promise->reject(TypeError);
        return;
    }

    // 6. Let origin be the origin of this object's Document.
    // This is retrieved in the following task.

    // 7. Let promise be a new promise.
    // 8. Run the following steps in parallel:
    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, weakThis = WeakPtr { *this }, sessionId, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
        // 8.1. Let sanitized session ID be a validated and/or sanitized version of sessionId.
        // 8.2. If the preceding step failed, or if sanitized session ID is empty, reject promise with a newly created TypeError.
        std::optional<String> sanitizedSessionId = m_implementation->sanitizeSessionId(sessionId);
        if (!sanitizedSessionId || sanitizedSessionId->isEmpty()) {
            INFO_LOG(identifier, "Rejected: sanitizedSSessionID empty");
            promise->reject(TypeError);
            return;
        }

        // 8.3. If there is a MediaKeySession object that is not closed in this object's Document whose sessionId attribute is sanitized session ID, reject promise with a QuotaExceededError.
        // FIXME: This needs a global MediaKeySession tracker.

        String origin;
        if (auto* document = downcast<Document>(scriptExecutionContext()))
            origin = document->securityOrigin().toString();

        // 8.4. Let expiration time be NaN.
        // 8.5. Let message be null.
        // 8.6. Let message type be null.
        // 8.7. Let cdm be the CDM instance represented by this object's cdm instance value.
        // 8.8. Use the cdm to execute the following steps:
        m_instanceSession->loadSession(m_sessionType, *sanitizedSessionId, origin, [this, weakThis, promise = WTFMove(promise), sanitizedSessionId = *sanitizedSessionId, identifier = WTFMove(identifier)] (std::optional<CDMInstanceSession::KeyStatusVector>&& knownKeys, std::optional<double>&& expiration, std::optional<CDMInstanceSession::Message>&& message, CDMInstanceSession::SuccessValue succeeded, CDMInstanceSession::SessionLoadFailure failure) mutable {
            // 8.8.1. If there is no data stored for the sanitized session ID in the origin, resolve promise with false and abort these steps.
            // 8.8.2. If the stored session's session type is not the same as the current MediaKeySession session type, reject promise with a newly created TypeError.
            // 8.8.3. Let session data be the data stored for the sanitized session ID in the origin. This must not include data from other origin(s) or that is not associated with an origin.
            // 8.8.4. If there is a MediaKeySession object that is not closed in any Document and that represents the session data, reject promise with a QuotaExceededError.
            // 8.8.5. Load the session data.
            // 8.8.6. If the session data indicates an expiration time for the session, let expiration time be the expiration time in milliseconds since 01 January 1970 UTC.
            // 8.8.7. If the CDM needs to send a message:
            //   8.8.7.1. Let message be a message generated by the CDM based on the session data.
            //   8.8.7.2. Let message type be the appropriate MediaKeyMessageType for the message.
            // NOTE: Steps 8.8.1. through 8.8.7. should be implemented in CDMInstance.

            if (succeeded == CDMInstanceSession::SuccessValue::Failed) {
                switch (failure) {
                case CDMInstanceSession::SessionLoadFailure::NoSessionData:
                    INFO_LOG(identifier, "::task() Resolved: NoSessionData");
                    promise->resolve<IDLBoolean>(false);
                    return;
                case CDMInstanceSession::SessionLoadFailure::MismatchedSessionType:
                    INFO_LOG(identifier, "::task() Rejected: MismatchedSessionType");
                    promise->reject(TypeError);
                    return;
                case CDMInstanceSession::SessionLoadFailure::QuotaExceeded:
                    INFO_LOG(identifier, "::task() Rejected: QuotaExceeded");
                    promise->reject(QuotaExceededError);
                    return;
                case CDMInstanceSession::SessionLoadFailure::None:
                case CDMInstanceSession::SessionLoadFailure::Other:
                    // In any other case, the session load failure will cause a rejection in the following task.
                    break;
                }
            }

            // 8.9. Queue a task to run the following steps:
            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, knownKeys = WTFMove(knownKeys), expiration = WTFMove(expiration), message = WTFMove(message), sanitizedSessionId, succeeded, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
                // 8.9.1. If any of the preceding steps failed, reject promise with a the appropriate error name.
                if (succeeded == CDMInstanceSession::SuccessValue::Failed) {
                    INFO_LOG(identifier, "::task() Rejected: Other failure");
                    promise->reject(NotSupportedError);
                    return;
                }

                // 8.9.2. Set the sessionId attribute to sanitized session ID.
                // 8.9.3. Let this object's callable value be true.
                m_sessionId = sanitizedSessionId;
                m_callable = true;

                // 8.9.4. If the loaded session contains information about any keys (there are known keys), run the Update Key Statuses algorithm on the session, providing each key's key ID along with the appropriate MediaKeyStatus.
                if (knownKeys)
                    updateKeyStatuses(WTFMove(*knownKeys));

                // 8.9.5. Run the Update Expiration algorithm on the session, providing expiration time.
                // This must be run, and NaN is the default value if the CDM instance doesn't provide one.
                updateExpiration(expiration.value_or(std::numeric_limits<double>::quiet_NaN()));

                // 8.9.6. If message is not null, run the Queue a "message" Event algorithm on the session, providing message type and message.
                if (message)
                    enqueueMessage(message->first, WTFMove(message->second));

                // 8.9.7. Resolve promise with true.
                INFO_LOG(identifier, "::task() Resolved");
                promise->resolve<IDLBoolean>(true);
            });
        });
    });

    // 9. Return promise.
}

void MediaKeySession::update(const BufferSource& response, Ref<DeferredPromise>&& promise)
{
    // https://w3c.github.io/encrypted-media/#dom-mediakeysession-update
    // W3C Editor's Draft 09 November 2016

    // When this method is invoked, the user agent must run the following steps:
    // 1. If this object is closed, return a promise rejected with an InvalidStateError.
    // 2. If this object's callable value is false, return a promise rejected with an InvalidStateError.
    auto identifier = LOGIDENTIFIER;
    INFO_LOG(identifier, "response.length(", response.length(), ")");

    if (m_closed || !m_callable) {
        INFO_LOG(identifier, "Rejected: closed(", m_closed, ") or !callable(", !m_callable, ")");
        promise->reject(InvalidStateError);
        return;
    }

    // 3. If response is an empty array, return a promise rejected with a newly created TypeError.
    if (!response.length()) {
        INFO_LOG(identifier, "Rejected: empty response");
        promise->reject(TypeError);
        return;
    }

    // 4. Let response copy be a copy of the contents of the response parameter.
    // 5. Let promise be a new promise.
    // 6. Run the following steps in parallel:
    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, weakThis = WeakPtr { *this }, response = SharedBuffer::create(response.data(), response.length()), promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
        // 6.1. Let sanitized response be a validated and/or sanitized version of response copy.
        RefPtr<FragmentedSharedBuffer> sanitizedResponse = m_implementation->sanitizeResponse(response);

        // 6.2. If the preceding step failed, or if sanitized response is empty, reject promise with a newly created TypeError.
        if (!sanitizedResponse || sanitizedResponse->isEmpty()) {
            INFO_LOG(identifier, "::task - Rejected: empty sanitized response");
            promise->reject(TypeError);
            return;
        }

        // 6.3. Let message be null.
        // 6.4. Let message type be null.
        // 6.5. Let session closed be false.
        // 6.6. Let cdm be the CDM instance represented by this object's cdm instance value.
        // 6.7. Use the cdm to execute the following steps:
        m_instanceSession->updateLicense(m_sessionId, m_sessionType, sanitizedResponse.releaseNonNull(), [this, weakThis, promise = WTFMove(promise), identifier = WTFMove(identifier)] (bool sessionWasClosed, std::optional<CDMInstanceSession::KeyStatusVector>&& changedKeys, std::optional<double>&& changedExpiration, std::optional<CDMInstanceSession::Message>&& message, CDMInstanceSession::SuccessValue succeeded) mutable {
            if (!weakThis)
                return;

            // 6.7.1. If the format of sanitized response is invalid in any way, reject promise with a newly created TypeError.
            // 6.7.2. Process sanitized response, following the stipulation for the first matching condition from the following list:
            //   ↳ If sanitized response contains a license or key(s)
            //     Process sanitized response, following the stipulation for the first matching condition from the following list:
            //     ↳ If sessionType is "temporary" and sanitized response does not specify that session data, including any license, key(s), or similar session data it contains, should be stored
            //       Process sanitized response, not storing any session data.
            //     ↳ If sessionType is "persistent-license" and sanitized response contains a persistable license
            //       Process sanitized response, storing the license/key(s) and related session data contained in sanitized response. Such data must be stored such that only the origin of this object's Document can access it.
            //     ↳ If sessionType is "persistent-usage-record" and sanitized response contains a non-persistable license
            //       Run the following steps:
            //         6.7.2.3.1. Process sanitized response, not storing any session data.
            //         6.7.2.3.2. If processing sanitized response results in the addition of keys to the set of known keys, add the key IDs of these keys to this object's record of key usage.
            //     ↳ Otherwise
            //       Reject promise with a newly created TypeError.
            //   ↳ If sanitized response contains a record of license destruction acknowledgement and sessionType is "persistent-license"
            //     Run the following steps:
            //       6.7.2.1. Close the key session and clear all stored session data associated with this object, including the sessionId and record of license destruction.
            //       6.7.2.2. Set session closed to true.
            //   ↳ Otherwise
            //     Process sanitized response, not storing any session data.
            // NOTE: Steps 6.7.1. and 6.7.2. should be implemented in CDMInstance.

            if (succeeded == CDMInstanceSession::SuccessValue::Failed) {
                INFO_LOG(identifier, "::task() Rejected");
                promise->reject(TypeError);
                return;
            }

            // 6.7.3. If a message needs to be sent to the server, execute the following steps:
            //   6.7.3.1. Let message be that message.
            //   6.7.3.2. Let message type be the appropriate MediaKeyMessageType for the message.
            // 6.8. Queue a task to run the following steps:
            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, sessionWasClosed, changedKeys = WTFMove(changedKeys), changedExpiration = WTFMove(changedExpiration), message = WTFMove(message), promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
                // 6.8.1.
                if (sessionWasClosed) {
                    // ↳ If session closed is true:
                    //   Run the Session Closed algorithm on this object.
                    sessionClosed();
                } else {
                    // ↳ Otherwise:
                    //   Run the following steps:
                    //     6.8.1.1. If the set of keys known to the CDM for this object changed or the status of any key(s) changed, run the Update Key Statuses
                    //              algorithm on the session, providing each known key's key ID along with the appropriate MediaKeyStatus. Should additional
                    //              processing be necessary to determine with certainty the status of a key, use "status-pending". Once the additional processing
                    //              for one or more keys has completed, run the Update Key Statuses algorithm again with the actual status(es).
                    if (changedKeys)
                        updateKeyStatuses(WTFMove(*changedKeys));

                    //     6.8.1.2. If the expiration time for the session changed, run the Update Expiration algorithm on the session, providing the new expiration time.
                    if (changedExpiration)
                        updateExpiration(*changedExpiration);

                    //     6.8.1.3. If any of the preceding steps failed, reject promise with a new DOMException whose name is the appropriate error name.
                    // FIXME: At this point the implementations of preceding steps can't fail.

                    //     6.8.1.4. If message is not null, run the Queue a "message" Event algorithm on the session, providing message type and message.
                    if (message) {
                        MediaKeyMessageType messageType;
                        switch (message->first) {
                        case CDMInstanceSession::MessageType::LicenseRequest:
                            messageType = MediaKeyMessageType::LicenseRequest;
                            break;
                        case CDMInstanceSession::MessageType::LicenseRenewal:
                            messageType = MediaKeyMessageType::LicenseRenewal;
                            break;
                        case CDMInstanceSession::MessageType::LicenseRelease:
                            messageType = MediaKeyMessageType::LicenseRelease;
                            break;
                        case CDMInstanceSession::MessageType::IndividualizationRequest:
                            messageType = MediaKeyMessageType::IndividualizationRequest;
                            break;
                        }

                        enqueueMessage(messageType, WTFMove(message->second));
                    }
                }

                // 6.8.2. Resolve promise.
                INFO_LOG(identifier, "::task() Resolved");
                promise->resolve();
            });
        });
    });

    // 7. Return promise.
}

void MediaKeySession::close(Ref<DeferredPromise>&& promise)
{
    // https://w3c.github.io/encrypted-media/#dom-mediakeysession-close
    // W3C Editor's Draft 09 November 2016

    auto identifier = LOGIDENTIFIER;
    INFO_LOG(identifier);

    // 1. Let session be the associated MediaKeySession object.
    // 2. If session is closed, return a resolved promise.
    LOG(EME, "EME - closing session %s", m_sessionId.utf8().data());

    if (m_closed) {
        INFO_LOG(identifier, "Resolved: already closed");
        promise->resolve();
        return;
    }

    // 3. If session's callable value is false, return a promise rejected with an InvalidStateError.
    if (!m_callable) {
        INFO_LOG(identifier, "Rejected: !callable");
        promise->reject(InvalidStateError);
        return;
    }

    // 4. Let promise be a new promise.
    // 5. Run the following steps in parallel:
    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, weakThis = WeakPtr { *this }, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
        // 5.1. Let cdm be the CDM instance represented by session's cdm instance value.
        // 5.2. Use cdm to close the key session associated with session.
        m_instanceSession->closeSession(m_sessionId, [this, weakThis, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
            if (!weakThis)
                return;

            // 5.3. Queue a task to run the following steps:
            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
                // 5.3.1. Run the Session Closed algorithm on the session.
                sessionClosed();

                // 5.3.2. Resolve promise.
                INFO_LOG(identifier, "::task() Resolved");
                promise->resolve();
            });
        });
    });

    // 6. Return promise.
}

void MediaKeySession::remove(Ref<DeferredPromise>&& promise)
{
    // https://w3c.github.io/encrypted-media/#dom-mediakeysession-remove
    // W3C Editor's Draft 09 November 2016

    // 1. If this object is closed, return a promise rejected with an InvalidStateError.
    // 2. If this object's callable value is false, return a promise rejected with an InvalidStateError.

    auto identifier = LOGIDENTIFIER;
    INFO_LOG(identifier);

    if (m_closed || !m_callable) {
        INFO_LOG(identifier, "Rejected: closed(", m_closed, ") or !callable(", !m_callable, ")");
        promise->reject(InvalidStateError);
        return;
    }

    // 3. Let promise be a new promise.
    // 4. Run the following steps in parallel:
    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, weakThis = WeakPtr { *this }, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
        // 4.1. Let cdm be the CDM instance represented by this object's cdm instance value.
        // 4.2. Let message be null.
        // 4.3. Let message type be null.

        // 4.4. Use the cdm to execute the following steps:
        m_instanceSession->removeSessionData(m_sessionId, m_sessionType, [this, weakThis, promise = WTFMove(promise), identifier = WTFMove(identifier)] (CDMInstanceSession::KeyStatusVector&& keys, std::optional<Ref<FragmentedSharedBuffer>>&& message, CDMInstanceSession::SuccessValue succeeded) mutable {
            if (!weakThis)
                return;

            // 4.4.1. If any license(s) and/or key(s) are associated with the session:
            //   4.4.1.1. Destroy the license(s) and/or key(s) associated with the session.
            //   4.4.1.2. Follow the steps for the value of this object's session type from the following list:
            //     ↳ "temporary"
            //       4.4.1.2.1.1 Continue with the following steps.
            //     ↳ "persistent-license"
            //       4.4.1.2.2.1. Let record of license destruction be a record of license destruction for the license represented by this object.
            //       4.4.1.2.2.2. Store the record of license destruction.
            //       4.4.1.2.2.3. Let message be a message containing or reflecting the record of license destruction.
            //     ↳ "persistent-usage-record"
            //       4.4.1.2.3.1. Store this object's record of key usage.
            //       4.4.1.2.3.2. Let message be a message containing or reflecting this object's record of key usage.
            // NOTE: Step 4.4.1. should be implemented in CDMInstance.

            // 4.5. Queue a task to run the following steps:
            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, keys = WTFMove(keys), message = WTFMove(message), succeeded, promise = WTFMove(promise), identifier = WTFMove(identifier)] () mutable {
                // 4.5.1. Run the Update Key Statuses algorithm on the session, providing all key ID(s) in the session along with the "released" MediaKeyStatus value for each.
                updateKeyStatuses(WTFMove(keys));

                // 4.5.2. Run the Update Expiration algorithm on the session, providing NaN.
                updateExpiration(std::numeric_limits<double>::quiet_NaN());

                // 4.5.3. If any of the preceding steps failed, reject promise with a new DOMException whose name is the appropriate error name.
                if (succeeded == CDMInstanceSession::SuccessValue::Failed) {
                    INFO_LOG(identifier, "Rejected: failed");
                    promise->reject(NotSupportedError);
                    return;
                }

                // 4.5.4. Let message type be "license-release".
                // 4.5.5. If message is not null, run the Queue a "message" Event algorithm on the session, providing message type and message.
                if (message)
                    enqueueMessage(MediaKeyMessageType::LicenseRelease, *message);

                // 4.5.6. Resolve promise.
                INFO_LOG(identifier, "Resolved");
                promise->resolve();
            });
        });
    });

    // 5. Return promise.
}

void MediaKeySession::enqueueMessage(MediaKeyMessageType messageType, const FragmentedSharedBuffer& message)
{
    // 6.4.1 Queue a "message" Event
    // https://w3c.github.io/encrypted-media/#queue-message
    // W3C Editor's Draft 09 November 2016

    // The following steps are run:
    // 1. Let the session be the specified MediaKeySession object.
    // 2. Queue a task to create an event named message that does not bubble and is not cancellable using the MediaKeyMessageEvent
    //    interface with its type attribute set to message and its isTrusted attribute initialized to true, and dispatch it at the
    //    session.
    auto messageEvent = MediaKeyMessageEvent::create(eventNames().messageEvent, {messageType, message.tryCreateArrayBuffer()}, Event::IsTrusted::Yes);
    queueTaskToDispatchEvent(*this, TaskSource::Networking, WTFMove(messageEvent));
}

void MediaKeySession::updateKeyStatuses(CDMInstanceSession::KeyStatusVector&& inputStatuses)
{
    // https://w3c.github.io/encrypted-media/#update-key-statuses
    // W3C Editor's Draft 09 November 2016

    // 1. Let the session be the associated MediaKeySession object.
    // 2. Let the input statuses be the sequence of pairs key ID and associated MediaKeyStatus pairs.
    // 3. Let the statuses be session's keyStatuses attribute.
    // 4. Run the following steps to replace the contents of statuses:
    //   4.1. Empty statuses.
    //   4.2. For each pair in input statuses.
    //     4.2.1. Let pair be the pair.
    //     4.2.2. Insert an entry for pair's key ID into statuses with the value of pair's MediaKeyStatus value.

    static auto toMediaKeyStatus = [] (CDMInstanceSession::KeyStatus status) -> MediaKeyStatus {
        switch (status) {
        case CDMInstanceSession::KeyStatus::Usable:
            return MediaKeyStatus::Usable;
        case CDMInstanceSession::KeyStatus::Expired:
            return MediaKeyStatus::Expired;
        case CDMInstanceSession::KeyStatus::Released:
            return MediaKeyStatus::Released;
        case CDMInstanceSession::KeyStatus::OutputRestricted:
            return MediaKeyStatus::OutputRestricted;
        case CDMInstanceSession::KeyStatus::OutputDownscaled:
            return MediaKeyStatus::OutputDownscaled;
        case CDMInstanceSession::KeyStatus::StatusPending:
            return MediaKeyStatus::StatusPending;
        case CDMInstanceSession::KeyStatus::InternalError:
            return MediaKeyStatus::InternalError;
        };

        ASSERT_NOT_REACHED();
        return MediaKeyStatus::InternalError;
    };

    m_statuses.clear();
    m_statuses.reserveCapacity(inputStatuses.size());
    for (auto& status : inputStatuses)
        m_statuses.uncheckedAppend({ WTFMove(status.first), toMediaKeyStatus(status.second) });

    // 5. Queue a task to fire a simple event named keystatuseschange at the session.
    queueTaskToDispatchEvent(*this, TaskSource::Networking, Event::create(eventNames().keystatuseschangeEvent, Event::CanBubble::No, Event::IsCancelable::No));

    // 6. Queue a task to run the Attempt to Resume Playback If Necessary algorithm on each of the media element(s) whose mediaKeys attribute is the MediaKeys object that created the session.
    queueTaskKeepingObjectAlive(*this, TaskSource::Networking,
        [this] () mutable {
            if (m_keys)
                m_keys->attemptToResumePlaybackOnClients();
        });
}

void MediaKeySession::sendMessage(CDMMessageType messageType, Ref<FragmentedSharedBuffer>&& message)
{
    enqueueMessage(messageType, message);
}

void MediaKeySession::sessionIdChanged(const String& sessionId)
{
    m_sessionId = sessionId;
}

PlatformDisplayID MediaKeySession::displayID()
{
    auto* document = downcast<Document>(scriptExecutionContext());
    if (!document)
        return 0;

    if (auto* page = document->page())
        return page->displayID();

    return 0;
}

void MediaKeySession::updateExpiration(double)
{
    notImplemented();
}

void MediaKeySession::sessionClosed()
{
    // https://w3c.github.io/encrypted-media/#session-closed
    // W3C Editor's Draft 09 November 2016
    INFO_LOG(LOGIDENTIFIER);

    // 1. Let session be the associated MediaKeySession object.
    // 2. If session's session type is "persistent-usage-record", execute the following steps in parallel:
    if (m_sessionType == MediaKeySessionType::PersistentUsageRecord) {
        // 2.1. Let cdm be the CDM instance represented by session's cdm instance value.
        // 2.2. Use cdm to store session's record of key usage, if it exists.
        m_instanceSession->storeRecordOfKeyUsage(m_sessionId);
    }

    // 3. Run the Update Key Statuses algorithm on the session, providing an empty sequence.
    updateKeyStatuses({ });

    // 4. Run the Update Expiration algorithm on the session, providing NaN.
    updateExpiration(std::numeric_limits<double>::quiet_NaN());

    // Let's consider the session closed before any promise on the 'closed' attribute is resolved.
    m_closed = true;

    // 5. Let promise be the closed attribute of the session.
    // 6. Resolve promise.
    m_closedPromise->resolve();
}

String MediaKeySession::mediaKeysStorageDirectory() const
{
    auto* document = downcast<Document>(scriptExecutionContext());
    if (!document)
        return emptyString();

    auto* page = document->page();
    if (!page || page->usesEphemeralSession())
        return emptyString();

    auto storageDirectory = document->settings().mediaKeysStorageDirectory();
    if (storageDirectory.isEmpty())
        return emptyString();

    return FileSystem::pathByAppendingComponent(storageDirectory, document->securityOrigin().data().databaseIdentifier());
}

bool MediaKeySession::virtualHasPendingActivity() const
{
    // A MediaKeySession object SHALL NOT be destroyed and SHALL continue to receive events if it is not closed and the MediaKeys object that created it remains accessible.
    return !m_closed && m_keys;
}

const char* MediaKeySession::activeDOMObjectName() const
{
    return "MediaKeySession";
}

#if !RELEASE_LOG_DISABLED
WTFLogChannel& MediaKeySession::logChannel() const
{
    return LogEME;
}
#endif

void MediaKeySession::displayChanged(PlatformDisplayID displayID)
{
    m_instanceSession->displayChanged(displayID);
}

} // namespace WebCore

#endif
