/*
 * Copyright (C) 2020 Igalia S.L. 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 "WebXRSystem.h"

#if ENABLE(WEBXR)

#include "DOMWindow.h"
#include "Document.h"
#include "FeaturePolicy.h"
#include "IDLTypes.h"
#include "JSWebXRSession.h"
#include "JSXRReferenceSpaceType.h"
#include "PlatformXR.h"
#include "RuntimeEnabledFeatures.h"
#include "SecurityOrigin.h"
#include "UserGestureIndicator.h"
#include "WebXRSession.h"
#include "XRReferenceSpaceType.h"
#include "XRSessionInit.h"
#include <JavaScriptCore/JSGlobalObject.h>
#include <wtf/IsoMallocInlines.h>
#include <wtf/Scope.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRSystem);

WebXRSystem::DummyInlineDevice::DummyInlineDevice()
{
    setEnabledFeatures(XRSessionMode::Inline, { XRReferenceSpaceType::Viewer });
}

Ref<WebXRSystem> WebXRSystem::create(ScriptExecutionContext& scriptExecutionContext)
{
    return adoptRef(*new WebXRSystem(scriptExecutionContext));
}

WebXRSystem::WebXRSystem(ScriptExecutionContext& scriptExecutionContext)
    : ActiveDOMObject(&scriptExecutionContext)
{
    m_inlineXRDevice = makeWeakPtr(m_defaultInlineDevice);
    suspendIfNeeded();
}

WebXRSystem::~WebXRSystem() = default;

// https://immersive-web.github.io/webxr/#ensures-an-immersive-xr-device-is-selected
void WebXRSystem::ensureImmersiveXRDeviceIsSelected()
{
    // Don't ask platform code for XR devices, we're using simulated ones.
    if (UNLIKELY(m_testingDevices))
        return;

    if (m_activeImmersiveDevice)
        return;

    // https://immersive-web.github.io/webxr/#enumerate-immersive-xr-devices
    auto& platformXR = PlatformXR::Instance::singleton();
    bool isFirstXRDevicesEnumeration = !m_immersiveXRDevicesHaveBeenEnumerated;
    platformXR.enumerateImmersiveXRDevices();
    m_immersiveXRDevicesHaveBeenEnumerated = true;
    const Vector<std::unique_ptr<PlatformXR::Device>>& immersiveXRDevices = platformXR.immersiveXRDevices();

    // https://immersive-web.github.io/webxr/#select-an-immersive-xr-device
    auto* oldDevice = m_activeImmersiveDevice.get();
    if (immersiveXRDevices.isEmpty()) {
        m_activeImmersiveDevice = nullptr;
        return;
    }
    if (immersiveXRDevices.size() == 1) {
        m_activeImmersiveDevice = makeWeakPtr(immersiveXRDevices.first().get());
        return;
    }

    if (m_activeImmersiveSession && oldDevice && immersiveXRDevices.findMatching([&] (auto& entry) { return entry.get() == oldDevice; }) != notFound)
        ASSERT(m_activeImmersiveDevice.get() == oldDevice);
    else {
        // TODO: implement a better UA selection mechanism if required.
        m_activeImmersiveDevice = makeWeakPtr(immersiveXRDevices.first().get());
    }

    if (isFirstXRDevicesEnumeration || m_activeImmersiveDevice.get() == oldDevice)
        return;

    // TODO: 7. Shut down any active XRSessions.
    // TODO: 8. Set the XR compatible boolean of all WebGLRenderingContextBase instances to false.
    // TODO: 9. Queue a task to fire an event named devicechange on the context object.
}


PlatformXR::Device* WebXRSystem::obtainCurrentDevice(XRSessionMode mode, const JSFeaturesArray& requiredFeatures, const JSFeaturesArray& optionalFeatures)
{
    if (mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr) {
        ensureImmersiveXRDeviceIsSelected();
        return m_activeImmersiveDevice.get();
    }
    if (!requiredFeatures.isEmpty() || !optionalFeatures.isEmpty())
        return m_inlineXRDevice.get();

    return &m_defaultInlineDevice;
}


// https://immersive-web.github.io/webxr/#dom-xrsystem-issessionsupported
void WebXRSystem::isSessionSupported(XRSessionMode mode, IsSessionSupportedPromise&& promise)
{
    // 1. Let promise be a new Promise.
    // 2. If mode is "inline", resolve promise with true and return it.
    if (mode == XRSessionMode::Inline) {
        promise.resolve(true);
        return;
    }

    // 3. If the requesting document's origin is not allowed to use the "xr-spatial-tracking" feature policy,
    //    reject promise with a "SecurityError" DOMException and return it.
    auto document = downcast<Document>(scriptExecutionContext());
    if (!isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::XRSpatialTracking, *document, LogFeaturePolicyFailure::Yes)) {
        promise.reject(Exception { SecurityError });
        return;
    }

    // 4. Run the following steps in parallel:
    scriptExecutionContext()->postTask([this, promise = WTFMove(promise), mode] (ScriptExecutionContext&) mutable {
        // 4.1 Ensure an immersive XR device is selected.
        ensureImmersiveXRDeviceIsSelected();

        // 4.2 If the immersive XR device is null, resolve promise with false and abort these steps.
        if (!m_activeImmersiveDevice) {
            promise.resolve(false);
            return;
        }

        // 4.3 If the immersive XR device's list of supported modes does not contain mode, resolve promise with false and abort these steps.
        if (!m_activeImmersiveDevice->supports(mode)) {
            promise.resolve(false);
            return;
        }

        // 4.4 Resolve promise with true.
        promise.resolve(true);
    });
}

// https://immersive-web.github.io/webxr/#immersive-session-request-is-allowed
bool WebXRSystem::immersiveSessionRequestIsAllowedForGlobalObject(DOMWindow& globalObject, Document& document) const
{
    // 1. If the request was not made while the global object has transient
    //    activation or when launching a web application, return false
    // TODO: add a check for "not launching a web application".
    if (!globalObject.hasTransientActivation())
        return false;

    // 2. If the requesting document is not considered trustworthy, return false.
    // https://immersive-web.github.io/webxr/#trustworthy.
    if (&document != globalObject.document())
        return false;

    // https://immersive-web.github.io/webxr/#active-and-focused
    if (!document.hasFocus() || !document.securityOrigin().isSameOriginAs(globalObject.document()->securityOrigin()))
        return false;

    // 3. If user intent to begin an immersive session is not well understood,
    //    either via explicit consent or implicit consent, return false
    if (!UserGestureIndicator::processingUserGesture())
        return false;

    return true;
}

// https://immersive-web.github.io/webxr/#inline-session-request-is-allowed
bool WebXRSystem::inlineSessionRequestIsAllowedForGlobalObject(DOMWindow& globalObject, Document& document, const XRSessionInit& init) const
{
    // 1. If the session request contained any required features or optional features and the request was not made
    //    while the global object has transient activation or when launching a web application, return false.
    bool sessionRequestContainedAnyFeature = !init.optionalFeatures.isEmpty() || !init.requiredFeatures.isEmpty();
    if (sessionRequestContainedAnyFeature && !globalObject.hasTransientActivation() /* TODO: || !launching a web app */)
        return false;

    // 2. If the requesting document is not responsible, return false.
    if (&document != globalObject.document())
        return false;

    return true;
}


struct WebXRSystem::ResolvedRequestedFeatures {
    FeaturesArray granted;
    FeaturesArray consentRequired;
    FeaturesArray consentOptional;
};

#define RETURN_FALSE_OR_CONTINUE(mustReturn) { \
    if (mustReturn) {\
        return false; \
    } \
    continue; \
}

// https://immersive-web.github.io/webxr/#resolve-the-requested-features
Optional<WebXRSystem::ResolvedRequestedFeatures> WebXRSystem::resolveRequestedFeatures(XRSessionMode mode, const XRSessionInit& init, PlatformXR::Device* device, JSC::JSGlobalObject& globalObject) const
{
    // 1. Let consentRequired be an empty list of DOMString.
    // 2. Let consentOptional be an empty list of DOMString.
    ResolvedRequestedFeatures resolvedFeatures;

    // 3. Let device be the result of obtaining the current device for mode, requiredFeatures, and optionalFeatures.
    // 4. Let granted be a list of DOMString initialized to device's list of enabled features for mode.
    // 5. If device is null or device's list of supported modes does not contain mode, run the following steps:
    //  5.1 Return the tuple (consentRequired, consentOptional, granted)
    if (!device || !device->supports(mode))
        return resolvedFeatures;

    resolvedFeatures.granted = device->enabledFeatures(mode);

    // 6. Add every feature descriptor in the default features table associated
    //    with mode to the indicated feature list if it is not already present.
    // https://immersive-web.github.io/webxr/#default-features
    auto requiredFeaturesWithDefaultFeatures = init.requiredFeatures;
    requiredFeaturesWithDefaultFeatures.append(convertEnumerationToJS(globalObject, XRReferenceSpaceType::Viewer));
    if (mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr)
        requiredFeaturesWithDefaultFeatures.append(convertEnumerationToJS(globalObject, XRReferenceSpaceType::Local));

    // 7. For each feature in requiredFeatures|optionalFeatures perform the following steps:
    // 8. For each feature in optionalFeatures perform the following steps:
    // We're merging both loops in a single lambda. The only difference is that a failure on any required features
    // implies cancelling the whole process while failures in optional features are just skipped.
    enum class ParsingMode { Strict, Loose };
    auto parseFeatures = [&device, &globalObject, mode, &resolvedFeatures] (const JSFeaturesArray& sessionFeatures, ParsingMode parsingMode) -> bool {
        bool returnOnFailure = parsingMode == ParsingMode::Strict;
        for (const auto& sessionFeature : sessionFeatures) {
            // 1. If the feature is null, continue to the next entry.
            if (sessionFeature.isNull())
                continue;

            // 2. If feature is not a valid feature descriptor, perform the following steps
            //   2.1. Let s be the result of calling ? ToString(feature).
            //   2.2. If s is not a valid feature descriptor or is undefined, (return null|continue to next entry).
            //   2.3. Set feature to s.
            auto feature = parseEnumeration<XRReferenceSpaceType>(globalObject, sessionFeature);
            if (!feature)
                RETURN_FALSE_OR_CONTINUE(returnOnFailure);

            // 3. If feature is already in granted, continue to the next entry.
            if (resolvedFeatures.granted.contains(feature.value()))
                continue;

            // 4. If the requesting document's origin is not allowed to use any feature policy required by feature
            //    as indicated by the feature requirements table, (return null|continue to next entry).

            // 5. If session's XR device is not capable of supporting the functionality described by feature or the
            //    user agent has otherwise determined to reject the feature, (return null|continue to next entry).
            if (!device->enabledFeatures(mode).contains(feature.value()))
                RETURN_FALSE_OR_CONTINUE(returnOnFailure);

            // 6. If the functionality described by feature requires explicit consent, append it to (consentRequired|consentOptional).
            // 7. Else append feature to granted.
            resolvedFeatures.granted.append(feature.value());
        }
        return true;
    };

    if (!parseFeatures(requiredFeaturesWithDefaultFeatures, ParsingMode::Strict))
        return WTF::nullopt;

    parseFeatures(init.optionalFeatures, ParsingMode::Loose);
    return resolvedFeatures;
}

// https://immersive-web.github.io/webxr/#request-the-xr-permission
bool WebXRSystem::isXRPermissionGranted(XRSessionMode mode, const XRSessionInit& init, PlatformXR::Device* device, JSC::JSGlobalObject& globalObject) const
{
    // 1. Set status's granted to an empty FrozenArray.
    // 2. Let requiredFeatures be descriptor's requiredFeatures.
    // 3. Let optionalFeatures be descriptor's optionalFeatures.
    // 4. Let device be the result of obtaining the current device for mode, requiredFeatures, and optionalFeatures.

    // 5. Let result be the result of resolving the requested features given requiredFeatures,optionalFeatures, and mode.
    auto resolvedFeatures = resolveRequestedFeatures(mode, init, device, globalObject);

    // 6. If result is null, run the following steps:
    //  6.1. Set status's state to "denied".
    //  6.2. Abort these steps.
    if (!resolvedFeatures)
        return false;

    // 7. Let (consentRequired, consentOptional, granted) be the fields of result.
    // 8. The user agent MAY at this point ask the user's permission for the calling algorithm to use any of the features
    //    in consentRequired and consentOptional. The results of these prompts should be included when determining if there
    //    is a clear signal of user intent for enabling these features.
    // 9. For each feature in consentRequired perform the following steps:
    //  9.1. The user agent MAY at this point ask the user's permission for the calling algorithm to use feature. The results
    //       of these prompts should be included when determining if there is a clear signal of user intent to enable feature.
    //  9.2. If a clear signal of user intent to enable feature has not been determined, set status's state to "denied" and
    //       abort these steps.
    //  9.3. If feature is not in granted, append feature to granted.
    // 10. For each feature in consentOptional perform the following steps:
    //  10.1. The user agent MAY at this point ask the user's permission for the calling algorithm to use feature. The results
    //        of these prompts should be included when determining if there is a clear signal of user intent to enable feature.
    //  10.2. If a clear signal of user intent to enable feature has not been determined, continue to the next entry.
    //  10.3. If feature is not in granted, append feature to granted.
    // 11. Set status's granted to granted.
    // 12. Set device's list of enabled features for mode to granted.
    // 13. Set status's state to "granted".
    return true;
}


// https://immersive-web.github.io/webxr/#dom-xrsystem-requestsession
void WebXRSystem::requestSession(Document& document, XRSessionMode mode, const XRSessionInit& init, RequestSessionPromise&& promise)
{
    // 1. Let promise be a new Promise.
    // 2. Let immersive be true if mode is an immersive session mode, and false otherwise.
    // 3. Let global object be the relevant Global object for the XRSystem on which this method was invoked.
    bool immersive = mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr;
    auto* globalObject = document.domWindow();
    if (!globalObject) {
        promise.reject(Exception { InvalidAccessError});
        return;
    }

    // 4. Check whether the session request is allowed as follows:
    if (immersive) {
        if (!immersiveSessionRequestIsAllowedForGlobalObject(*globalObject, document)) {
            promise.reject(Exception { SecurityError });
            return;
        }
        if (m_pendingImmersiveSession || m_activeImmersiveSession) {
            promise.reject(Exception { InvalidStateError });
            return;
        }
        m_pendingImmersiveSession = true;
    } else if (!inlineSessionRequestIsAllowedForGlobalObject(*globalObject, document, init)) {
        promise.reject(Exception { SecurityError });
        return;
    }

    // 5. Run the following steps in parallel:
    queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, document = makeWeakPtr(document), immersive, init, mode, promise = WTFMove(promise)] () mutable {
        // 5.1 Let requiredFeatures be options' requiredFeatures.
        // 5.2 Let optionalFeatures be options' optionalFeatures.
        // 5.3 Set device to the result of obtaining the current device for mode, requiredFeatures, and optionalFeatures.
        auto* device = obtainCurrentDevice(mode, init.requiredFeatures, init.optionalFeatures);

        // 5.4 Queue a task to perform the following steps:
        queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, document = WTFMove(document), device = makeWeakPtr(device), immersive, init, mode, promise = WTFMove(promise)] () mutable {
            auto rejectPromiseWithNotSupportedError = makeScopeExit([&] () {
                promise.reject(Exception { NotSupportedError });
                m_pendingImmersiveSession = false;
            });

            // 5.4.1 If device is null or device's list of supported modes does not contain mode, run the following steps:
            //  - Reject promise with a "NotSupportedError" DOMException.
            //  - If immersive is true, set pending immersive session to false.
            //  - Abort these steps.
            if (!device || !device->supports(mode))
                return;

            auto* globalObject = document ? document->execState() : nullptr;
            if (!globalObject)
                return;

            // WebKit does not currently support the Permissions API. https://w3c.github.io/permissions/
            // However we do implement here the permission request algorithm without the
            // Permissions API bits as it handles, among others, the session features parsing. We also
            // do it here before creating the session as there is no need to do it on advance.
            // TODO: we just perform basic checks without asking any permission to the user so far. Maybe we should implement
            // a mechanism similar to what others do involving passing a message to the UI process.

            // 5.4.4 Let descriptor be an XRPermissionDescriptor initialized with session, requiredFeatures, and optionalFeatures
            // 5.4.5 Let status be an XRPermissionStatus, initially null
            // 5.4.6 Request the xr permission with descriptor and status.
            // 5.4.7 If status' state is "denied" run the following steps: (same as above in 5.4.1)
            if (!isXRPermissionGranted(mode, init, device.get(), *globalObject))
                return;

            // 5.4.2 Let session be a new XRSession object.
            // 5.4.3 Initialize the session with session, mode, and device.
            auto session = WebXRSession::create(*document, *this, mode, *device);

            // 5.4.8 Potentially set the active immersive session as follows:
            if (immersive) {
                m_activeImmersiveSession = session.copyRef();
                m_pendingImmersiveSession = false;
            } else
                m_inlineSessions.add(session.copyRef());

            // 5.4.9 Resolve promise with session.
            promise.resolve(session);
            rejectPromiseWithNotSupportedError.release();

            // TODO:
            // 5.4.10 Queue a task to perform the following steps: NOTE: These steps ensure that initial inputsourceschange
            // events occur after the initial session is resolved.
            //     1. Set session's promise resolved flag to true.
            //     2. Let sources be any existing input sources attached to session.
            //     3. If sources is non-empty, perform the following steps:
            //        1. Set session's list of active XR input sources to sources.
            //        2. Fire an XRInputSourcesChangeEvent named inputsourceschange on session with added set to sources.

        });
    });
}

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

void WebXRSystem::stop()
{
}

void WebXRSystem::registerSimulatedXRDeviceForTesting(PlatformXR::Device& device)
{
    if (!RuntimeEnabledFeatures::sharedFeatures().webXREnabled())
        return;
    m_testingDevices++;
    if (device.supports(XRSessionMode::ImmersiveVr) || device.supports(XRSessionMode::ImmersiveAr)) {
        m_immersiveDevices.add(device);
        m_activeImmersiveDevice = makeWeakPtr(device);
    }
    if (device.supports(XRSessionMode::Inline))
        m_inlineXRDevice = makeWeakPtr(device);
}

void WebXRSystem::unregisterSimulatedXRDeviceForTesting(PlatformXR::Device& device)
{
    if (!RuntimeEnabledFeatures::sharedFeatures().webXREnabled())
        return;
    ASSERT(m_testingDevices);
    bool removed = m_immersiveDevices.remove(device);
    ASSERT_UNUSED(removed, removed || m_inlineXRDevice == &device);
    if (m_activeImmersiveDevice == &device)
        m_activeImmersiveDevice = nullptr;
    if (m_inlineXRDevice == &device)
        m_inlineXRDevice = makeWeakPtr(m_defaultInlineDevice);
    m_testingDevices--;
}

void WebXRSystem::sessionEnded(WebXRSession& session)
{
    if (m_activeImmersiveSession == &session)
        m_activeImmersiveSession = nullptr;

    m_inlineSessions.remove(session);
}

} // namespace WebCore

#endif // ENABLE(WEBXR)
