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

#import "config.h"
#import "WKWebViewPrivateForTesting.h"

#import "AudioSessionRoutingArbitratorProxy.h"
#import "GPUProcessProxy.h"
#import "MediaSessionCoordinatorProxyPrivate.h"
#import "PlaybackSessionManagerProxy.h"
#import "UserMediaProcessManager.h"
#import "ViewGestureController.h"
#import "WebPageProxy.h"
#import "WebProcessPool.h"
#import "WebProcessProxy.h"
#import "WebViewImpl.h"
#import "_WKFrameHandleInternal.h"
#import "_WKInspectorInternal.h"
#import <WebCore/RuntimeApplicationChecks.h>
#import <WebCore/ValidationBubble.h>
#import <wtf/RetainPtr.h>

#if PLATFORM(MAC)
#import "WKWebViewMac.h"
#endif

#if PLATFORM(IOS_FAMILY)
#import "WKWebViewIOS.h"
#endif

#if ENABLE(MEDIA_SESSION_COORDINATOR)
@interface WKMediaSessionCoordinatorHelper : NSObject <_WKMediaSessionCoordinatorDelegate>
- (id)initWithCoordinator:(WebCore::MediaSessionCoordinatorClient*)coordinator;
- (void)seekSessionToTime:(double)time withCompletion:(void(^)(BOOL))completionHandler;
- (void)playSessionWithCompletion:(void(^)(BOOL))completionHandler;
- (void)pauseSessionWithCompletion:(void(^)(BOOL))completionHandler;
- (void)setSessionTrack:(NSString*)trackIdentifier withCompletion:(void(^)(BOOL))completionHandler;
- (void)coordinatorStateChanged:(_WKMediaSessionCoordinatorState)state;
@end
#endif

@implementation WKWebView (WKTesting)

- (void)_addEventAttributionWithSourceID:(uint8_t)sourceID destinationURL:(NSURL *)destination sourceDescription:(NSString *)sourceDescription purchaser:(NSString *)purchaser reportEndpoint:(NSURL *)reportEndpoint optionalNonce:(NSString *)nonce applicationBundleID:(NSString *)bundleID ephemeral:(BOOL)ephemeral
{
    WebCore::PrivateClickMeasurement measurement(
        WebCore::PrivateClickMeasurement::SourceID(sourceID),
        WebCore::PrivateClickMeasurement::SourceSite(reportEndpoint),
        WebCore::PrivateClickMeasurement::AttributionDestinationSite(destination),
        bundleID,
        WallTime::now(),
        ephemeral ? WebCore::PrivateClickMeasurement::AttributionEphemeral::Yes : WebCore::PrivateClickMeasurement::AttributionEphemeral::No
    );
    if (nonce)
        measurement.setEphemeralSourceNonce({ nonce });

    _page->setPrivateClickMeasurement({{ WTFMove(measurement), { }, { }}});
}

- (void)_setPageScale:(CGFloat)scale withOrigin:(CGPoint)origin
{
    _page->scalePage(scale, WebCore::roundedIntPoint(origin));
}

- (CGFloat)_pageScale
{
    return _page->pageScaleFactor();
}

- (void)_setContinuousSpellCheckingEnabledForTesting:(BOOL)enabled
{
#if PLATFORM(IOS_FAMILY)
    [_contentView setContinuousSpellCheckingEnabled:enabled];
#else
    _impl->setContinuousSpellCheckingEnabled(enabled);
#endif
}

- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
{
    if ([userInterfaceItem isEqualToString:@"validationBubble"]) {
        auto* validationBubble = _page->validationBubble();
        String message = validationBubble ? validationBubble->message() : emptyString();
        double fontSize = validationBubble ? validationBubble->fontSize() : 0;
        return @{ userInterfaceItem: @{ @"message": (NSString *)message, @"fontSize": @(fontSize) } };
    }

    if (NSDictionary *contents = _page->contentsOfUserInterfaceItem(userInterfaceItem))
        return contents;

#if PLATFORM(IOS_FAMILY)
    return [_contentView _contentsOfUserInterfaceItem:(NSString *)userInterfaceItem];
#else
    return nil;
#endif
}

- (void)_requestActiveNowPlayingSessionInfo:(void(^)(BOOL, BOOL, NSString*, double, double, NSInteger))callback
{
    if (!_page) {
        callback(NO, NO, @"", std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), 0);
        return;
    }

    _page->requestActiveNowPlayingSessionInfo([handler = makeBlockPtr(callback)] (bool active, bool registeredAsNowPlayingApplication, String title, double duration, double elapsedTime, uint64_t uniqueIdentifier) {
        handler(active, registeredAsNowPlayingApplication, title, duration, elapsedTime, uniqueIdentifier);
    });
}

- (BOOL)_scrollingUpdatesDisabledForTesting
{
    // For subclasses to override;
    return NO;
}

- (void)_setScrollingUpdatesDisabledForTesting:(BOOL)disabled
{
}

- (void)_doAfterNextPresentationUpdateWithoutWaitingForAnimatedResizeForTesting:(void (^)(void))updateBlock
{
    [self _internalDoAfterNextPresentationUpdate:updateBlock withoutWaitingForPainting:NO withoutWaitingForAnimatedResize:YES];
}

- (void)_doAfterNextVisibleContentRectUpdate:(void (^)(void))updateBlock
{
#if PLATFORM(IOS_FAMILY)
    _visibleContentRectUpdateCallbacks.append(makeBlockPtr(updateBlock));
    [self _scheduleVisibleContentRectUpdate];
#else
    RunLoop::main().dispatch([updateBlock = makeBlockPtr(updateBlock)] {
        updateBlock();
    });
#endif
}

- (void)_disableBackForwardSnapshotVolatilityForTesting
{
    WebKit::ViewSnapshotStore::singleton().setDisableSnapshotVolatilityForTesting(true);
}

- (BOOL)_beginBackSwipeForTesting
{
#if PLATFORM(MAC)
    return _impl->beginBackSwipeForTesting();
#else
    if (!_gestureController)
        return NO;
    return _gestureController->beginSimulatedSwipeInDirectionForTesting(WebKit::ViewGestureController::SwipeDirection::Back);
#endif
}

- (BOOL)_completeBackSwipeForTesting
{
#if PLATFORM(MAC)
    return _impl->completeBackSwipeForTesting();
#else
    if (!_gestureController)
        return NO;
    return _gestureController->completeSimulatedSwipeInDirectionForTesting(WebKit::ViewGestureController::SwipeDirection::Back);
#endif
}

- (void)_resetNavigationGestureStateForTesting
{
#if PLATFORM(MAC)
    if (auto gestureController = _impl->gestureController())
        gestureController->reset();
#else
    if (_gestureController)
        _gestureController->reset();
#endif
}

- (void)_setDefersLoadingForTesting:(BOOL)defersLoading
{
    _page->setDefersLoadingForTesting(defersLoading);
}

- (void)_setShareSheetCompletesImmediatelyWithResolutionForTesting:(BOOL)resolved
{
    _resolutionForShareSheetImmediateCompletionForTesting = resolved;
}

- (void)_processWillSuspendForTesting:(void (^)(void))completionHandler
{
    if (!_page) {
        completionHandler();
        return;
    }
    _page->process().sendPrepareToSuspend(WebKit::IsSuspensionImminent::No, [completionHandler = makeBlockPtr(completionHandler)] {
        completionHandler();
    });
}

- (void)_processWillSuspendImminentlyForTesting
{
    if (_page)
        _page->process().sendPrepareToSuspend(WebKit::IsSuspensionImminent::Yes, [] { });
}

- (void)_processDidResumeForTesting
{
    if (_page)
        _page->process().sendProcessDidResume();
}

- (void)_setAssertionTypeForTesting:(int)value
{
    if (!_page)
        return;

    _page->process().setAssertionTypeForTesting(static_cast<WebKit::ProcessAssertionType>(value));
}

- (BOOL)_hasServiceWorkerBackgroundActivityForTesting
{
#if ENABLE(SERVICE_WORKER)
    return _page ? _page->process().processPool().hasServiceWorkerBackgroundActivityForTesting() : false;
#else
    return false;
#endif
}

- (BOOL)_hasServiceWorkerForegroundActivityForTesting
{
#if ENABLE(SERVICE_WORKER)
    return _page ? _page->process().processPool().hasServiceWorkerForegroundActivityForTesting() : false;
#else
    return false;
#endif
}

- (void)_denyNextUserMediaRequest
{
#if ENABLE(MEDIA_STREAM)
    WebKit::UserMediaProcessManager::singleton().denyNextUserMediaRequest();
#endif
}

- (void)_setIndexOfGetDisplayMediaDeviceSelectedForTesting:(NSNumber *)nsIndex
{
#if HAVE(SCREEN_CAPTURE_KIT)
    if (!_page)
        return;

    std::optional<unsigned> index;
    if (nsIndex)
        index = nsIndex.unsignedIntValue;

    _page->setIndexOfGetDisplayMediaDeviceSelectedForTesting(index);
#endif
}

- (double)_mediaCaptureReportingDelayForTesting
{
    return _page->mediaCaptureReportingDelay().value();
}

- (void)_setMediaCaptureReportingDelayForTesting:(double)captureReportingDelay
{
    _page->setMediaCaptureReportingDelay(Seconds(captureReportingDelay));
}

- (BOOL)_wirelessVideoPlaybackDisabled
{
#if ENABLE(VIDEO_PRESENTATION_MODE)
    if (auto* playbackSessionManager = _page->playbackSessionManager())
        return playbackSessionManager->wirelessVideoPlaybackDisabled();
#endif
    return false;
}

- (void)_doAfterProcessingAllPendingMouseEvents:(dispatch_block_t)action
{
    _page->doAfterProcessingAllPendingMouseEvents([action = makeBlockPtr(action)] {
        action();
    });
}

+ (void)_setApplicationBundleIdentifier:(NSString *)bundleIdentifier
{
    WebCore::setApplicationBundleIdentifierOverride(String(bundleIdentifier));
}

+ (void)_clearApplicationBundleIdentifierTestingOverride
{
    WebCore::clearApplicationBundleIdentifierTestingOverride();
}

- (BOOL)_hasSleepDisabler
{
    return _page && _page->process().hasSleepDisabler();
}

- (WKWebViewAudioRoutingArbitrationStatus)_audioRoutingArbitrationStatus
{
#if ENABLE(ROUTING_ARBITRATION)
    switch (_page->process().audioSessionRoutingArbitrator().arbitrationStatus()) {
    case WebKit::AudioSessionRoutingArbitratorProxy::ArbitrationStatus::None: return WKWebViewAudioRoutingArbitrationStatusNone;
    case WebKit::AudioSessionRoutingArbitratorProxy::ArbitrationStatus::Pending: return WKWebViewAudioRoutingArbitrationStatusPending;
    case WebKit::AudioSessionRoutingArbitratorProxy::ArbitrationStatus::Active: return WKWebViewAudioRoutingArbitrationStatusActive;
    default: ASSERT_NOT_REACHED();
    }
#else
    return WKWebViewAudioRoutingArbitrationStatusNone;
#endif
}

- (double)_audioRoutingArbitrationUpdateTime
{
#if ENABLE(ROUTING_ARBITRATION)
    return _page->process().audioSessionRoutingArbitrator().arbitrationUpdateTime().secondsSinceEpoch().seconds();
#else
    return 0;
#endif
}

- (void)_doAfterActivityStateUpdate:(void (^)(void))completionHandler
{
    _page->addActivityStateUpdateCompletionHandler(makeBlockPtr(completionHandler));
}

- (NSNumber *)_suspendMediaPlaybackCounter
{
    return @(_page->suspendMediaPlaybackCounter());
}

- (void)_setPrivateClickMeasurementOverrideTimerForTesting:(BOOL)overrideTimer completionHandler:(void(^)(void))completionHandler
{
    _page->setPrivateClickMeasurementOverrideTimerForTesting(overrideTimer, [completionHandler = makeBlockPtr(completionHandler)] {
        completionHandler();
    });
}

- (void)_setPrivateClickMeasurementAttributionReportURLsForTesting:(NSURL *)sourceURL destinationURL:(NSURL *)destinationURL completionHandler:(void(^)(void))completionHandler
{
    _page->setPrivateClickMeasurementAttributionReportURLsForTesting(sourceURL, destinationURL, [completionHandler = makeBlockPtr(completionHandler)] {
        completionHandler();
    });
}

- (void)_setPrivateClickMeasurementAttributionTokenPublicKeyURLForTesting:(NSURL *)url completionHandler:(void(^)(void))completionHandler
{
    _page->setPrivateClickMeasurementTokenPublicKeyURLForTesting(url, [completionHandler = makeBlockPtr(completionHandler)] {
        completionHandler();
    });
}

- (void)_setPrivateClickMeasurementAttributionTokenSignatureURLForTesting:(NSURL *)url completionHandler:(void(^)(void))completionHandler
{
    _page->setPrivateClickMeasurementTokenSignatureURLForTesting(url, [completionHandler = makeBlockPtr(completionHandler)] {
        completionHandler();
    });
}

- (void)_setPrivateClickMeasurementAppBundleIDForTesting:(NSString *)appBundleID completionHandler:(void(^)(void))completionHandler
{
    _page->setPrivateClickMeasurementAppBundleIDForTesting(appBundleID, [completionHandler = makeBlockPtr(completionHandler)] {
        completionHandler();
    });
}

- (void)_dumpPrivateClickMeasurement:(void(^)(NSString *))completionHandler
{
    _page->dumpPrivateClickMeasurement([completionHandler = makeBlockPtr(completionHandler)](const String& privateClickMeasurement) {
        completionHandler(privateClickMeasurement);
    });
}

- (void)_didShowContextMenu
{
    // For subclasses to override.
}

- (void)_didDismissContextMenu
{
    // For subclasses to override.
}

- (void)_didPresentContactPicker
{
    // For subclasses to override.
}

- (void)_didDismissContactPicker
{
    // For subclasses to override.
}

- (void)_dismissContactPickerWithContacts:(NSArray *)contacts
{
#if PLATFORM(IOS_FAMILY)
    [_contentView _dismissContactPickerWithContacts:contacts];
#endif
}

- (void)_lastNavigationWasAppInitiated:(void(^)(BOOL))completionHandler
{
    _page->lastNavigationWasAppInitiated([completionHandler = makeBlockPtr(completionHandler)] (bool isAppInitiated) {
        completionHandler(isAppInitiated);
    });
}

- (void)_appPrivacyReportTestingData:(void(^)(struct WKAppPrivacyReportTestingData data))completionHandler
{
    _page->appPrivacyReportTestingData([completionHandler = makeBlockPtr(completionHandler)] (auto&& appPrivacyReportTestingData) {
        completionHandler({ appPrivacyReportTestingData.hasLoadedAppInitiatedRequestTesting, appPrivacyReportTestingData.hasLoadedNonAppInitiatedRequestTesting, appPrivacyReportTestingData.didPerformSoftUpdate });
    });
}

- (void)_clearAppPrivacyReportTestingData:(void(^)(void))completionHandler
{
    _page->clearAppPrivacyReportTestingData([completionHandler = makeBlockPtr(completionHandler)] {
        completionHandler();
    });
}

- (void)_isLayerTreeFrozenForTesting:(void (^)(BOOL frozen))completionHandler
{
    _page->isLayerTreeFrozen([completionHandler = makeBlockPtr(completionHandler)](bool isFrozen) {
        completionHandler(isFrozen);
    });
}

- (void)_gpuToWebProcessConnectionCountForTesting:(void(^)(NSUInteger))completionHandler
{
    RefPtr gpuProcess = _page->process().processPool().gpuProcess();
    if (!gpuProcess) {
        completionHandler(0);
        return;
    }

    gpuProcess->webProcessConnectionCountForTesting([completionHandler = makeBlockPtr(completionHandler)](uint64_t count) {
        completionHandler(count);
    });
}

- (void)_createMediaSessionCoordinatorForTesting:(id <_WKMediaSessionCoordinator>)privateCoordinator completionHandler:(void(^)(BOOL))completionHandler
{
#if ENABLE(MEDIA_SESSION_COORDINATOR)
    class WKMediaSessionCoordinatorForTesting
        : public WebKit::MediaSessionCoordinatorProxyPrivate
        , public WebCore::MediaSessionCoordinatorClient {
        WTF_MAKE_FAST_ALLOCATED;
    public:

        static Ref<WKMediaSessionCoordinatorForTesting> create(id <_WKMediaSessionCoordinator> privateCoordinator)
        {
            return adoptRef(*new WKMediaSessionCoordinatorForTesting(privateCoordinator));
        }

        using WebCore::MediaSessionCoordinatorClient::weakPtrFactory;
        using WeakValueType = WebCore::MediaSessionCoordinatorClient::WeakValueType;

    private:
        explicit WKMediaSessionCoordinatorForTesting(id <_WKMediaSessionCoordinator> clientCoordinator)
            : WebKit::MediaSessionCoordinatorProxyPrivate()
            , m_clientCoordinator(clientCoordinator)
        {
            auto* delegateHelper = [[WKMediaSessionCoordinatorHelper alloc] initWithCoordinator:this];
            [m_clientCoordinator setDelegate:delegateHelper];
            m_coordinatorDelegate = adoptNS(delegateHelper);
        }

        void seekSessionToTime(double time, CompletionHandler<void(bool)>&& callback) final
        {
            if (auto coordinatorClient = client())
                coordinatorClient->seekSessionToTime(time, WTFMove(callback));
            else
                callback(false);
        }

        void playSession(std::optional<double> atTime, std::optional<MonotonicTime> hostTime, CompletionHandler<void(bool)>&& callback) final
        {
            if (auto coordinatorClient = client())
                coordinatorClient->playSession(WTFMove(atTime), WTFMove(hostTime), WTFMove(callback));
            else
                callback(false);
        }

        void pauseSession(CompletionHandler<void(bool)>&& callback) final
        {
            if (auto coordinatorClient = client())
                coordinatorClient->pauseSession(WTFMove(callback));
            else
                callback(false);
        }

        void setSessionTrack(const String& trackIdentifier, CompletionHandler<void(bool)>&& callback) final
        {
            if (auto coordinatorClient = client())
                coordinatorClient->setSessionTrack(trackIdentifier, WTFMove(callback));
            else
                callback(false);
        }

        void coordinatorStateChanged(WebCore::MediaSessionCoordinatorState state) final
        {
            if (auto coordinatorClient = client())
                coordinatorClient->coordinatorStateChanged(state);
        }

        std::optional<WebCore::ExceptionData> result(bool success) const
        {
            if (!success)
                return { WebCore::ExceptionData { WebCore::InvalidStateError, String() } };

            return { };
        }

        String identifier() const
        {
            return [m_clientCoordinator identifier];
        }

        void join(WebKit::MediaSessionCommandCompletionHandler&& callback) final
        {
            [m_clientCoordinator joinWithCompletion:makeBlockPtr([weakThis = WeakPtr { *this }, callback = WTFMove(callback)] (BOOL success) mutable {
                if (!weakThis) {
                    callback(WebCore::ExceptionData { WebCore::InvalidStateError, String() });
                    return;
                }

                callback(weakThis->result(success));
            }).get()];
        }

        void leave() final
        {
            [m_clientCoordinator leave];
        }

        void seekTo(double time, WebKit::MediaSessionCommandCompletionHandler&& callback) final
        {
            [m_clientCoordinator seekTo:time withCompletion:makeBlockPtr([weakThis = WeakPtr { *this }, callback = WTFMove(callback)] (BOOL success) mutable {
                if (!weakThis) {
                    callback(WebCore::ExceptionData { WebCore::InvalidStateError, String() });
                    return;
                }

                callback(weakThis->result(success));
            }).get()];
        }

        void play(WebKit::MediaSessionCommandCompletionHandler&& callback) final
        {
            [m_clientCoordinator playWithCompletion:makeBlockPtr([weakThis = WeakPtr { *this }, callback = WTFMove(callback)] (BOOL success) mutable {
                if (!weakThis) {
                    callback(WebCore::ExceptionData { WebCore::InvalidStateError, String() });
                    return;
                }

                callback(weakThis->result(success));
            }).get()];
        }

        void pause(WebKit::MediaSessionCommandCompletionHandler&& callback) final
        {
            [m_clientCoordinator pauseWithCompletion:makeBlockPtr([weakThis = WeakPtr { *this }, callback = WTFMove(callback)] (BOOL success) mutable {
                if (!weakThis) {
                    callback(WebCore::ExceptionData { WebCore::InvalidStateError, String() });
                    return;
                }

                callback(weakThis->result(success));
            }).get()];
        }

        void setTrack(const String& track, WebKit::MediaSessionCommandCompletionHandler&& callback) final
        {
            [m_clientCoordinator setTrack:track withCompletion:makeBlockPtr([weakThis = WeakPtr { *this }, callback = WTFMove(callback)] (BOOL success) mutable {
                if (!weakThis) {
                    callback(WebCore::ExceptionData { WebCore::InvalidStateError, String() });
                    return;
                }

                callback(weakThis->result(success));
            }).get()];
        }

        void positionStateChanged(const std::optional<WebCore::MediaPositionState>& state) final
        {
            if (!state) {
                [m_clientCoordinator positionStateChanged:nil];
                return;
            }

            _WKMediaPositionState position = {
                .duration = state->duration,
                .playbackRate = state->playbackRate,
                .position = state->position
            };
            [m_clientCoordinator positionStateChanged:&position];
        }

        void readyStateChanged(WebCore::MediaSessionReadyState state) final
        {
            static_assert(static_cast<size_t>(WebCore::MediaSessionReadyState::Havenothing) == static_cast<size_t>(WKMediaSessionReadyStateHaveNothing), "WKMediaSessionReadyStateHaveNothing does not match WebKit value");
            static_assert(static_cast<size_t>(WebCore::MediaSessionReadyState::Havemetadata) == static_cast<size_t>(WKMediaSessionReadyStateHaveMetadata), "WKMediaSessionReadyStateHaveMetadata does not match WebKit value");
            static_assert(static_cast<size_t>(WebCore::MediaSessionReadyState::Havecurrentdata) == static_cast<size_t>(WKMediaSessionReadyStateHaveCurrentData), "WKMediaSessionReadyStateHaveCurrentData does not match WebKit value");
            static_assert(static_cast<size_t>(WebCore::MediaSessionReadyState::Havefuturedata) == static_cast<size_t>(WKMediaSessionReadyStateHaveFutureData), "WKMediaSessionReadyStateHaveFutureData does not match WebKit value");
            static_assert(static_cast<size_t>(WebCore::MediaSessionReadyState::Haveenoughdata) == static_cast<size_t>(WKMediaSessionReadyStateHaveEnoughData), "WKMediaSessionReadyStateHaveEnoughData does not match WebKit value");

            [m_clientCoordinator readyStateChanged:static_cast<_WKMediaSessionReadyState>(state)];
        }

        void playbackStateChanged(WebCore::MediaSessionPlaybackState state) final
        {
            static_assert(static_cast<size_t>(WebCore::MediaSessionPlaybackState::None) == static_cast<size_t>(WKMediaSessionPlaybackStateNone), "WKMediaSessionPlaybackStateNone does not match WebKit value");
            static_assert(static_cast<size_t>(WebCore::MediaSessionPlaybackState::Paused) == static_cast<size_t>(WKMediaSessionPlaybackStatePaused), "WKMediaSessionPlaybackStatePaused does not match WebKit value");
            static_assert(static_cast<size_t>(WebCore::MediaSessionPlaybackState::Playing) == static_cast<size_t>(WKMediaSessionPlaybackStatePlaying), "WKMediaSessionPlaybackStatePlaying does not match WebKit value");

            [m_clientCoordinator playbackStateChanged:static_cast<_WKMediaSessionPlaybackState>(state)];
        }

        void trackIdentifierChanged(const String& identifier) final
        {
            [m_clientCoordinator trackIdentifierChanged:identifier];
        }

    private:
        RetainPtr<id <_WKMediaSessionCoordinator>> m_clientCoordinator;
        RetainPtr<WKMediaSessionCoordinatorHelper> m_coordinatorDelegate;
    };

    ASSERT(!_impl->mediaSessionCoordinatorForTesting());

    _impl->setMediaSessionCoordinatorForTesting(WKMediaSessionCoordinatorForTesting::create(privateCoordinator).ptr());
    _impl->page().createMediaSessionCoordinator(*_impl->mediaSessionCoordinatorForTesting(), [completionHandler = makeBlockPtr(completionHandler)] (bool success) {
        completionHandler(success);
    });
#else

    completionHandler(NO);

#endif
}

@end

#if ENABLE(MEDIA_SESSION_COORDINATOR)
@implementation WKMediaSessionCoordinatorHelper {
    WeakPtr<WebCore::MediaSessionCoordinatorClient> m_coordinatorClient;
}

- (id)initWithCoordinator:(WebCore::MediaSessionCoordinatorClient*)coordinator
{
    self = [super init];
    if (!self)
        return nil;
    m_coordinatorClient = coordinator;
    return self;
}

- (void)seekSessionToTime:(double)time withCompletion:(void(^)(BOOL))completionHandler
{
    m_coordinatorClient->seekSessionToTime(time, makeBlockPtr(completionHandler));
}

- (void)playSessionWithCompletion:(void(^)(BOOL))completionHandler
{
    m_coordinatorClient->playSession({ }, std::optional<MonotonicTime>(), makeBlockPtr(completionHandler));
}

- (void)pauseSessionWithCompletion:(void(^)(BOOL))completionHandler
{
    m_coordinatorClient->pauseSession(makeBlockPtr(completionHandler));
}

- (void)setSessionTrack:(NSString*)trackIdentifier withCompletion:(void(^)(BOOL))completionHandler
{
    m_coordinatorClient->setSessionTrack(trackIdentifier, makeBlockPtr(completionHandler));
}

- (void)coordinatorStateChanged:(_WKMediaSessionCoordinatorState)state
{
    static_assert(static_cast<size_t>(WebCore::MediaSessionCoordinatorState::Waiting) == static_cast<size_t>(WKMediaSessionCoordinatorStateWaiting), "WKMediaSessionCoordinatorStateWaiting does not match WebKit value");
    static_assert(static_cast<size_t>(WebCore::MediaSessionCoordinatorState::Joined) == static_cast<size_t>(WKMediaSessionCoordinatorStateJoined), "WKMediaSessionCoordinatorStateJoined does not match WebKit value");
    static_assert(static_cast<size_t>(WebCore::MediaSessionCoordinatorState::Closed) == static_cast<size_t>(WKMediaSessionCoordinatorStateClosed), "WKMediaSessionCoordinatorStateClosed does not match WebKit value");

    m_coordinatorClient->coordinatorStateChanged(static_cast<WebCore::MediaSessionCoordinatorState>(state));
}

@end
#endif
