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

#import "ArgumentCodersCF.h"
#import "ArgumentCodersCocoa.h"
#import <CoreText/CoreText.h>
#import <WebCore/AttributedString.h>
#import <WebCore/DataDetectorElementInfo.h>
#import <WebCore/DictionaryPopupInfo.h>
#import <WebCore/Font.h>
#import <WebCore/FontAttributes.h>
#import <WebCore/FontCustomPlatformData.h>
#import <WebCore/ResourceRequest.h>
#import <WebCore/TextRecognitionResult.h>
#import <pal/spi/cf/CoreTextSPI.h>

#if PLATFORM(IOS_FAMILY)
#import <UIKit/UIFont.h>
#endif

#if ENABLE(WIRELESS_PLAYBACK_TARGET)
#import <WebCore/MediaPlaybackTargetContext.h>
#import <objc/runtime.h>
#endif

#if USE(APPLE_INTERNAL_SDK)
#include <WebKitAdditions/WebCoreArgumentCodersCocoaAdditions.mm>
#endif

#if USE(AVFOUNDATION)
#import <wtf/MachSendRight.h>
#endif

#if ENABLE(APPLE_PAY)
#import "DataReference.h"
#import <WebCore/PaymentAuthorizationStatus.h>
#import <pal/cocoa/PassKitSoftLink.h>
#endif

#if ENABLE(WIRELESS_PLAYBACK_TARGET)
#import <pal/cocoa/AVFoundationSoftLink.h>
#endif

#if ENABLE(DATA_DETECTION)
#import <pal/cocoa/DataDetectorsCoreSoftLink.h>
#endif

#if USE(AVFOUNDATION)
#import <WebCore/CoreVideoSoftLink.h>
#endif

namespace IPC {

void ArgumentCoder<WebCore::AttributedString>::encode(Encoder& encoder, const WebCore::AttributedString& attributedString)
{
    encoder << attributedString.string << attributedString.documentAttributes;
}

std::optional<WebCore::AttributedString> ArgumentCoder<WebCore::AttributedString>::decode(Decoder& decoder)
{
    RetainPtr<NSAttributedString> attributedString;
    if (!IPC::decode(decoder, attributedString))
        return std::nullopt;
    RetainPtr<NSDictionary> documentAttributes;
    if (!IPC::decode(decoder, documentAttributes))
        return std::nullopt;
    return { { WTFMove(attributedString), WTFMove(documentAttributes) } };
}

#if ENABLE(APPLE_PAY)

#if HAVE(PASSKIT_INSTALLMENTS)

void ArgumentCoder<WebCore::PaymentInstallmentConfiguration>::encode(Encoder& encoder, const WebCore::PaymentInstallmentConfiguration& configuration)
{
    encoder << configuration.platformConfiguration();
}

std::optional<WebCore::PaymentInstallmentConfiguration> ArgumentCoder<WebCore::PaymentInstallmentConfiguration>::decode(Decoder& decoder)
{
    auto configuration = IPC::decode<PKPaymentInstallmentConfiguration>(decoder, PAL::getPKPaymentInstallmentConfigurationClass());
    if (!configuration)
        return std::nullopt;

    return { WTFMove(*configuration) };
}

#endif // HAVE(PASSKIT_INSTALLMENTS)

void ArgumentCoder<WebCore::Payment>::encode(Encoder& encoder, const WebCore::Payment& payment)
{
    encoder << payment.pkPayment();
}

std::optional<WebCore::Payment> ArgumentCoder<WebCore::Payment>::decode(Decoder& decoder)
{
    auto payment = IPC::decode<PKPayment>(decoder, PAL::getPKPaymentClass());
    if (!payment)
        return std::nullopt;

    return WebCore::Payment { WTFMove(*payment) };
}

void ArgumentCoder<WebCore::PaymentAuthorizationResult>::encode(Encoder& encoder, const WebCore::PaymentAuthorizationResult& result)
{
    encoder << result.status;
    encoder << result.errors;
}

std::optional<WebCore::PaymentAuthorizationResult> ArgumentCoder<WebCore::PaymentAuthorizationResult>::decode(Decoder& decoder)
{
    std::optional<WebCore::PaymentAuthorizationStatus> status;
    decoder >> status;
    if (!status)
        return std::nullopt;

    std::optional<Vector<RefPtr<WebCore::ApplePayError>>> errors;
    decoder >> errors;
    if (!errors)
        return std::nullopt;

    return {{ WTFMove(*status), WTFMove(*errors) }};
}

void ArgumentCoder<WebCore::PaymentContact>::encode(Encoder& encoder, const WebCore::PaymentContact& paymentContact)
{
    encoder << paymentContact.pkContact();
}

std::optional<WebCore::PaymentContact> ArgumentCoder<WebCore::PaymentContact>::decode(Decoder& decoder)
{
    auto contact = IPC::decode<PKContact>(decoder, PAL::getPKContactClass());
    if (!contact)
        return std::nullopt;

    return WebCore::PaymentContact { WTFMove(*contact) };
}

void ArgumentCoder<WebCore::PaymentMerchantSession>::encode(Encoder& encoder, const WebCore::PaymentMerchantSession& paymentMerchantSession)
{
    encoder << paymentMerchantSession.pkPaymentMerchantSession();
}

std::optional<WebCore::PaymentMerchantSession> ArgumentCoder<WebCore::PaymentMerchantSession>::decode(Decoder& decoder)
{
    auto paymentMerchantSession = IPC::decode<PKPaymentMerchantSession>(decoder, PAL::getPKPaymentMerchantSessionClass());
    if (!paymentMerchantSession)
        return std::nullopt;

    return WebCore::PaymentMerchantSession { WTFMove(*paymentMerchantSession) };
}

void ArgumentCoder<WebCore::PaymentMethod>::encode(Encoder& encoder, const WebCore::PaymentMethod& paymentMethod)
{
    encoder << paymentMethod.pkPaymentMethod();
}

std::optional<WebCore::PaymentMethod> ArgumentCoder<WebCore::PaymentMethod>::decode(Decoder& decoder)
{
    auto paymentMethod = IPC::decode<PKPaymentMethod>(decoder, PAL::getPKPaymentMethodClass());
    if (!paymentMethod)
        return std::nullopt;

    return WebCore::PaymentMethod { WTFMove(*paymentMethod) };
}

void ArgumentCoder<WebCore::ApplePaySessionPaymentRequest>::encode(Encoder& encoder, const WebCore::ApplePaySessionPaymentRequest& request)
{
    encoder << request.countryCode();
    encoder << request.currencyCode();
    encoder << request.requiredBillingContactFields();
    encoder << request.billingContact();
    encoder << request.requiredShippingContactFields();
    encoder << request.shippingContact();
    encoder << request.merchantCapabilities();
    encoder << request.supportedNetworks();
    encoder << request.shippingType();
    encoder << request.shippingMethods();
    encoder << request.lineItems();
    encoder << request.total();
    encoder << request.applicationData();
    encoder << request.supportedCountries();
    encoder << request.requester();
#if ENABLE(APPLE_PAY_INSTALLMENTS)
    encoder << request.installmentConfiguration();
#endif
#if ENABLE(APPLE_PAY_COUPON_CODE)
    encoder << request.supportsCouponCode();
    encoder << request.couponCode();
#endif
#if ENABLE(APPLE_PAY_SHIPPING_CONTACT_EDITING_MODE)
    encoder << request.shippingContactEditingMode();
#endif
#if defined(WebCoreArgumentCodersCocoaAdditions_ApplePaySessionPaymentRequest_encode)
    WebCoreArgumentCodersCocoaAdditions_ApplePaySessionPaymentRequest_encode
#endif
}

bool ArgumentCoder<WebCore::ApplePaySessionPaymentRequest>::decode(Decoder& decoder, WebCore::ApplePaySessionPaymentRequest& request)
{
    String countryCode;
    if (!decoder.decode(countryCode))
        return false;
    request.setCountryCode(countryCode);

    String currencyCode;
    if (!decoder.decode(currencyCode))
        return false;
    request.setCurrencyCode(currencyCode);

    WebCore::ApplePaySessionPaymentRequest::ContactFields requiredBillingContactFields;
    if (!decoder.decode((requiredBillingContactFields)))
        return false;
    request.setRequiredBillingContactFields(requiredBillingContactFields);

    std::optional<WebCore::PaymentContact> billingContact;
    decoder >> billingContact;
    if (!billingContact)
        return false;
    request.setBillingContact(*billingContact);

    WebCore::ApplePaySessionPaymentRequest::ContactFields requiredShippingContactFields;
    if (!decoder.decode((requiredShippingContactFields)))
        return false;
    request.setRequiredShippingContactFields(requiredShippingContactFields);

    std::optional<WebCore::PaymentContact> shippingContact;
    decoder >> shippingContact;
    if (!shippingContact)
        return false;
    request.setShippingContact(*shippingContact);

    WebCore::ApplePaySessionPaymentRequest::MerchantCapabilities merchantCapabilities;
    if (!decoder.decode(merchantCapabilities))
        return false;
    request.setMerchantCapabilities(merchantCapabilities);

    Vector<String> supportedNetworks;
    if (!decoder.decode(supportedNetworks))
        return false;
    request.setSupportedNetworks(supportedNetworks);

    WebCore::ApplePaySessionPaymentRequest::ShippingType shippingType;
    if (!decoder.decode(shippingType))
        return false;
    request.setShippingType(shippingType);

    Vector<WebCore::ApplePayShippingMethod> shippingMethods;
    if (!decoder.decode(shippingMethods))
        return false;
    request.setShippingMethods(shippingMethods);

    Vector<WebCore::ApplePayLineItem> lineItems;
    if (!decoder.decode(lineItems))
        return false;
    request.setLineItems(lineItems);

    std::optional<WebCore::ApplePayLineItem> total;
    decoder >> total;
    if (!total)
        return false;
    request.setTotal(*total);

    String applicationData;
    if (!decoder.decode(applicationData))
        return false;
    request.setApplicationData(applicationData);

    Vector<String> supportedCountries;
    if (!decoder.decode(supportedCountries))
        return false;
    request.setSupportedCountries(WTFMove(supportedCountries));

    WebCore::ApplePaySessionPaymentRequest::Requester requester;
    if (!decoder.decode(requester))
        return false;
    request.setRequester(requester);
    
#if ENABLE(APPLE_PAY_INSTALLMENTS)
    std::optional<WebCore::PaymentInstallmentConfiguration> installmentConfiguration;
    decoder >> installmentConfiguration;
    if (!installmentConfiguration)
        return false;

    request.setInstallmentConfiguration(WTFMove(*installmentConfiguration));
#endif

#if ENABLE(APPLE_PAY_COUPON_CODE)
    std::optional<std::optional<bool>> supportsCouponCode;
    decoder >> supportsCouponCode;
    if (!supportsCouponCode)
        return false;
    request.setSupportsCouponCode(WTFMove(*supportsCouponCode));

    std::optional<String> couponCode;
    decoder >> couponCode;
    if (!couponCode)
        return false;
    request.setCouponCode(WTFMove(*couponCode));
#endif

#if ENABLE(APPLE_PAY_SHIPPING_CONTACT_EDITING_MODE)
    std::optional<std::optional<WebCore::ApplePayShippingContactEditingMode>> shippingContactEditingMode;
    decoder >> shippingContactEditingMode;
    if (!shippingContactEditingMode)
        return false;
    request.setShippingContactEditingMode(WTFMove(*shippingContactEditingMode));
#endif

#if defined(WebCoreArgumentCodersCocoaAdditions_ApplePaySessionPaymentRequest_decode)
    WebCoreArgumentCodersCocoaAdditions_ApplePaySessionPaymentRequest_decode
#endif

    return true;
}

void ArgumentCoder<WebCore::ApplePaySessionPaymentRequest::ContactFields>::encode(Encoder& encoder, const WebCore::ApplePaySessionPaymentRequest::ContactFields& contactFields)
{
    encoder << contactFields.postalAddress;
    encoder << contactFields.phone;
    encoder << contactFields.email;
    encoder << contactFields.name;
    encoder << contactFields.phoneticName;
}

bool ArgumentCoder<WebCore::ApplePaySessionPaymentRequest::ContactFields>::decode(Decoder& decoder, WebCore::ApplePaySessionPaymentRequest::ContactFields& contactFields)
{
    if (!decoder.decode(contactFields.postalAddress))
        return false;
    if (!decoder.decode(contactFields.phone))
        return false;
    if (!decoder.decode(contactFields.email))
        return false;
    if (!decoder.decode(contactFields.name))
        return false;
    if (!decoder.decode(contactFields.phoneticName))
        return false;

    return true;
}

void ArgumentCoder<WebCore::ApplePaySessionPaymentRequest::MerchantCapabilities>::encode(Encoder& encoder, const WebCore::ApplePaySessionPaymentRequest::MerchantCapabilities& merchantCapabilities)
{
    encoder << merchantCapabilities.supports3DS;
    encoder << merchantCapabilities.supportsEMV;
    encoder << merchantCapabilities.supportsCredit;
    encoder << merchantCapabilities.supportsDebit;
}

bool ArgumentCoder<WebCore::ApplePaySessionPaymentRequest::MerchantCapabilities>::decode(Decoder& decoder, WebCore::ApplePaySessionPaymentRequest::MerchantCapabilities& merchantCapabilities)
{
    if (!decoder.decode(merchantCapabilities.supports3DS))
        return false;
    if (!decoder.decode(merchantCapabilities.supportsEMV))
        return false;
    if (!decoder.decode(merchantCapabilities.supportsCredit))
        return false;
    if (!decoder.decode(merchantCapabilities.supportsDebit))
        return false;

    return true;
}

void ArgumentCoder<RefPtr<WebCore::ApplePayError>>::encode(Encoder& encoder, const RefPtr<WebCore::ApplePayError>& error)
{
    encoder << !!error;
    if (error)
        encoder << *error;
}

std::optional<RefPtr<WebCore::ApplePayError>> ArgumentCoder<RefPtr<WebCore::ApplePayError>>::decode(Decoder& decoder)
{
    std::optional<bool> isValid;
    decoder >> isValid;
    if (!isValid)
        return std::nullopt;

    RefPtr<WebCore::ApplePayError> error;
    if (!*isValid)
        return { nullptr };

    error = WebCore::ApplePayError::decode(decoder);
    if (!error)
        return std::nullopt;
    return error;
}

void ArgumentCoder<WebCore::PaymentSessionError>::encode(Encoder& encoder, const WebCore::PaymentSessionError& error)
{
    encoder << error.platformError();
}

std::optional<WebCore::PaymentSessionError> ArgumentCoder<WebCore::PaymentSessionError>::decode(Decoder& decoder)
{
    auto platformError = IPC::decode<NSError>(decoder);
    if (!platformError)
        return std::nullopt;

    return { WTFMove(*platformError) };
}

#endif // ENABLE(APPLEPAY)

void ArgumentCoder<WebCore::DictionaryPopupInfo>::encodePlatformData(Encoder& encoder, const WebCore::DictionaryPopupInfo& info)
{
    encoder << info.options << info.attributedString;
}

bool ArgumentCoder<WebCore::DictionaryPopupInfo>::decodePlatformData(Decoder& decoder, WebCore::DictionaryPopupInfo& result)
{
    if (!IPC::decode(decoder, result.options))
        return false;
    if (!IPC::decode(decoder, result.attributedString))
        return false;
    return true;
}

void ArgumentCoder<WebCore::FontAttributes>::encodePlatformData(Encoder& encoder, const WebCore::FontAttributes& attributes)
{
    encoder << attributes.font;
}

std::optional<WebCore::FontAttributes> ArgumentCoder<WebCore::FontAttributes>::decodePlatformData(Decoder& decoder, WebCore::FontAttributes& attributes)
{
    if (!IPC::decode(decoder, attributes.font))
        return std::nullopt;
    return attributes;
}

void ArgumentCoder<Ref<WebCore::Font>>::encodePlatformData(Encoder& encoder, const Ref<WebCore::Font>& font)
{
    const auto& platformData = font->platformData();
    encoder << platformData.orientation();
    encoder << platformData.widthVariant();
    encoder << platformData.textRenderingMode();
    encoder << platformData.size();
    encoder << platformData.syntheticBold();
    encoder << platformData.syntheticOblique();

    auto ctFont = platformData.font();
    auto fontDescriptor = adoptCF(CTFontCopyFontDescriptor(ctFont));
    auto attributes = adoptCF(CTFontDescriptorCopyAttributes(fontDescriptor.get()));
    encoder << attributes;

    const auto& creationData = platformData.creationData();
    encoder << static_cast<bool>(creationData);
    if (creationData) {
        encoder << creationData->fontFaceData;
        encoder << creationData->itemInCollection;
    } else {
        auto referenceURL = adoptCF(static_cast<CFURLRef>(CTFontCopyAttribute(ctFont, kCTFontReferenceURLAttribute)));
        auto string = CFURLGetString(referenceURL.get());
        encoder << String(string);
        encoder << String(adoptCF(CTFontCopyPostScriptName(ctFont)).get());
    }
}

static RetainPtr<CTFontDescriptorRef> findFontDescriptor(const String& referenceURL, const String& postScriptName)
{
    auto url = adoptCF(CFURLCreateWithString(kCFAllocatorDefault, referenceURL.createCFString().get(), nullptr));
    if (!url)
        return nullptr;
    auto fontDescriptors = adoptCF(CTFontManagerCreateFontDescriptorsFromURL(url.get()));
    if (!fontDescriptors || !CFArrayGetCount(fontDescriptors.get()))
        return nullptr;
    if (CFArrayGetCount(fontDescriptors.get()) == 1)
        return static_cast<CTFontDescriptorRef>(CFArrayGetValueAtIndex(fontDescriptors.get(), 0));

    for (CFIndex i = 0; i < CFArrayGetCount(fontDescriptors.get()); ++i) {
        auto fontDescriptor = static_cast<CTFontDescriptorRef>(CFArrayGetValueAtIndex(fontDescriptors.get(), i));
        auto currentPostScriptName = adoptCF(static_cast<CFStringRef>(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontNameAttribute)));
        if (String(currentPostScriptName.get()) == postScriptName)
            return fontDescriptor;
    }
    return nullptr;
}

static RetainPtr<CTFontRef> createCTFont(CFDictionaryRef attributes, float size, const String& referenceURL, const String& desiredPostScriptName)
{
    auto fontDescriptor = adoptCF(CTFontDescriptorCreateWithAttributes(attributes));
    if (fontDescriptor) {
        auto font = adoptCF(CTFontCreateWithFontDescriptorAndOptions(fontDescriptor.get(), size, nullptr, kCTFontOptionsSystemUIFont));
        String actualPostScriptName(adoptCF(CTFontCopyPostScriptName(font.get())).get());
        if (actualPostScriptName == desiredPostScriptName)
            return font;
    }

    // CoreText couldn't round-trip the font.
    // We can fall back to doing our best to find it ourself.
    fontDescriptor = findFontDescriptor(referenceURL, desiredPostScriptName);
    if (!fontDescriptor) {
        ASSERT_NOT_REACHED();
        fontDescriptor = adoptCF(CTFontDescriptorCreateLastResort());
    }
    ASSERT(fontDescriptor);
    return adoptCF(CTFontCreateWithFontDescriptorAndOptions(fontDescriptor.get(), size, nullptr, kCTFontOptionsSystemUIFont));
}

std::optional<WebCore::FontPlatformData> ArgumentCoder<Ref<WebCore::Font>>::decodePlatformData(Decoder& decoder)
{
    std::optional<WebCore::FontOrientation> orientation;
    decoder >> orientation;
    if (!orientation)
        return std::nullopt;

    std::optional<WebCore::FontWidthVariant> widthVariant;
    decoder >> widthVariant;
    if (!widthVariant)
        return std::nullopt;

    std::optional<WebCore::TextRenderingMode> textRenderingMode;
    decoder >> textRenderingMode;
    if (!textRenderingMode)
        return std::nullopt;

    std::optional<float> size;
    decoder >> size;
    if (!size)
        return std::nullopt;

    std::optional<bool> syntheticBold;
    decoder >> syntheticBold;
    if (!syntheticBold)
        return std::nullopt;

    std::optional<bool> syntheticOblique;
    decoder >> syntheticOblique;
    if (!syntheticOblique)
        return std::nullopt;

    std::optional<RetainPtr<CFDictionaryRef>> attributes;
    decoder >> attributes;
    if (!attributes)
        return std::nullopt;

    std::optional<bool> includesCreationData;
    decoder >> includesCreationData;
    if (!includesCreationData)
        return std::nullopt;

    if (*includesCreationData) {
        std::optional<Ref<WebCore::SharedBuffer>> fontFaceData;
        decoder >> fontFaceData;
        if (!fontFaceData)
            return std::nullopt;

        // Upon receipt, copy the data for security, so the sender can't scribble over it while we're using it.
        auto localFontFaceData = WebCore::SharedBuffer::create(fontFaceData.value()->data(), fontFaceData.value()->size());

        std::optional<String> itemInCollection;
        decoder >> itemInCollection;
        if (!itemInCollection)
            return std::nullopt;

        auto fontCustomPlatformData = createFontCustomPlatformData(localFontFaceData, *itemInCollection);
        if (!fontCustomPlatformData)
            return std::nullopt;
        auto baseFontDescriptor = fontCustomPlatformData->fontDescriptor.get();
        if (!baseFontDescriptor)
            return std::nullopt;
        auto fontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithAttributes(baseFontDescriptor, attributes->get()));
        auto ctFont = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), *size, nullptr));

        auto creationData = WebCore::FontPlatformData::CreationData { localFontFaceData, *itemInCollection };
        return WebCore::FontPlatformData(ctFont.get(), *size, *syntheticBold, *syntheticOblique, *orientation, *widthVariant, *textRenderingMode, &creationData);
    }

    std::optional<String> referenceURL;
    decoder >> referenceURL;
    if (!referenceURL)
        return std::nullopt;

    std::optional<String> postScriptName;
    decoder >> postScriptName;
    if (!postScriptName)
        return std::nullopt;

    auto ctFont = createCTFont(attributes->get(), *size, *referenceURL, *postScriptName);
    if (!ctFont)
        return std::nullopt;

    return WebCore::FontPlatformData(ctFont.get(), *size, *syntheticBold, *syntheticOblique, *orientation, *widthVariant, *textRenderingMode);
}

void ArgumentCoder<WebCore::ResourceRequest>::encodePlatformData(Encoder& encoder, const WebCore::ResourceRequest& resourceRequest)
{
    auto requestToSerialize = retainPtr(resourceRequest.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody));

    if (Class requestClass = [requestToSerialize class]; UNLIKELY(requestClass != [NSURLRequest class] && requestClass != [NSMutableURLRequest class])) {
        WebCore::ResourceRequest request(requestToSerialize.get());
        request.replacePlatformRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody);
        requestToSerialize = retainPtr(request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody));
    }
    ASSERT([requestToSerialize class] == [NSURLRequest class] || [requestToSerialize class] == [NSMutableURLRequest class]);

    bool requestIsPresent = requestToSerialize;
    encoder << requestIsPresent;

    if (!requestIsPresent)
        return;

    // We don't send HTTP body over IPC for better performance.
    // Also, it's not always possible to do, as streams can only be created in process that does networking.
    if ([requestToSerialize HTTPBody] || [requestToSerialize HTTPBodyStream]) {
        auto mutableRequest = adoptNS([requestToSerialize mutableCopy]);
        [mutableRequest setHTTPBody:nil];
        [mutableRequest setHTTPBodyStream:nil];
        requestToSerialize = WTFMove(mutableRequest);
    }

    IPC::encode(encoder, requestToSerialize.get());

    encoder << resourceRequest.requester();
    encoder << resourceRequest.isAppInitiated();
}

bool ArgumentCoder<WebCore::ResourceRequest>::decodePlatformData(Decoder& decoder, WebCore::ResourceRequest& resourceRequest)
{
    bool requestIsPresent;
    if (!decoder.decode(requestIsPresent))
        return false;

    if (!requestIsPresent) {
        resourceRequest = WebCore::ResourceRequest();
        return true;
    }

    auto request = IPC::decode<NSURLRequest>(decoder, NSURLRequest.class);
    if (!request)
        return false;
    
    WebCore::ResourceRequest::Requester requester;
    if (!decoder.decode(requester))
        return false;

    bool isAppInitiated;
    if (!decoder.decode(isAppInitiated))
        return false;

    resourceRequest = WebCore::ResourceRequest(request->get());
    resourceRequest.setRequester(requester);
    resourceRequest.setIsAppInitiated(isAppInitiated);

    return true;
}

#if ENABLE(DATA_DETECTION)

void ArgumentCoder<WebCore::DataDetectorElementInfo>::encode(Encoder& encoder, const WebCore::DataDetectorElementInfo& info)
{
    encoder << info.result.get();
    encoder << info.elementBounds;
}

std::optional<WebCore::DataDetectorElementInfo> ArgumentCoder<WebCore::DataDetectorElementInfo>::decode(Decoder& decoder)
{
    auto result = IPC::decode<DDScannerResult>(decoder, PAL::getDDScannerResultClass());
    if (!result)
        return std::nullopt;

    std::optional<WebCore::IntRect> elementBounds;
    decoder >> elementBounds;
    if (!elementBounds)
        return std::nullopt;

    return std::make_optional<WebCore::DataDetectorElementInfo>({ WTFMove(*result), WTFMove(*elementBounds) });
}

#endif // ENABLE(DATA_DETECTION)

#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void ArgumentCoder<WebCore::MediaPlaybackTargetContext>::encodePlatformData(Encoder& encoder, const WebCore::MediaPlaybackTargetContext& target)
{
    if (target.type() == WebCore::MediaPlaybackTargetContext::Type::AVOutputContext) {
        if ([PAL::getAVOutputContextClass() conformsToProtocol:@protocol(NSSecureCoding)])
            encoder << target.outputContext();
    } else if (target.type() == WebCore::MediaPlaybackTargetContext::Type::SerializedAVOutputContext) {
        encoder << target.serializedOutputContext();
        encoder << target.hasActiveRoute();
    } else
        ASSERT_NOT_REACHED();
}

bool ArgumentCoder<WebCore::MediaPlaybackTargetContext>::decodePlatformData(Decoder& decoder, WebCore::MediaPlaybackTargetContext::Type contextType, WebCore::MediaPlaybackTargetContext& target)
{
    ASSERT(contextType != WebCore::MediaPlaybackTargetContext::Type::Mock);

    if (contextType == WebCore::MediaPlaybackTargetContext::Type::AVOutputContext) {
        if (![PAL::getAVOutputContextClass() conformsToProtocol:@protocol(NSSecureCoding)])
            return false;

        auto outputContext = IPC::decode<AVOutputContext>(decoder, PAL::getAVOutputContextClass());
        if (!outputContext)
            return false;

        target = WebCore::MediaPlaybackTargetContext { WTFMove(*outputContext) };
        return true;
    }

    if (contextType == WebCore::MediaPlaybackTargetContext::Type::SerializedAVOutputContext) {
        RetainPtr<NSData> serializedOutputContext;
        if (!IPC::decode(decoder, serializedOutputContext) || !serializedOutputContext)
            return false;

        bool hasActiveRoute;
        if (!decoder.decode(hasActiveRoute))
            return false;

        target = WebCore::MediaPlaybackTargetContext { WTFMove(serializedOutputContext), hasActiveRoute };
        return true;
    }

    return false;
}
#endif

#if ENABLE(IMAGE_ANALYSIS) && ENABLE(DATA_DETECTION)

void ArgumentCoder<WebCore::TextRecognitionDataDetector>::encodePlatformData(Encoder& encoder, const WebCore::TextRecognitionDataDetector& info)
{
    encoder << info.result.get();
}

bool ArgumentCoder<WebCore::TextRecognitionDataDetector>::decodePlatformData(Decoder& decoder, WebCore::TextRecognitionDataDetector& result)
{
    auto scannerResult = IPC::decode<DDScannerResult>(decoder, @[ PAL::getDDScannerResultClass() ]);
    if (!scannerResult)
        return false;

    result.result = WTFMove(*scannerResult);
    return true;
}

#endif // ENABLE(IMAGE_ANALYSIS) && ENABLE(DATA_DETECTION)

#if USE(AVFOUNDATION)

void ArgumentCoder<RetainPtr<CVPixelBufferRef>>::encode(Encoder& encoder, const RetainPtr<CVPixelBufferRef>& pixelBuffer)
{
    // Use IOSurface as the means to transfer CVPixelBufferRef.
    MachSendRight sendRight;
    if (pixelBuffer) {
        if (auto surface = WebCore::CVPixelBufferGetIOSurface(pixelBuffer.get()))
            sendRight = MachSendRight::adopt(IOSurfaceCreateMachPort(surface));
    }
    encoder << WTFMove(sendRight);
}

std::optional<RetainPtr<CVPixelBufferRef>> ArgumentCoder<RetainPtr<CVPixelBufferRef>>::decode(Decoder& decoder)
{
    std::optional<MachSendRight> sendRight;
    decoder >> sendRight;
    if (!sendRight)
        return std::nullopt;
    RetainPtr<CVPixelBufferRef> pixelBuffer;
    if (!*sendRight)
        return pixelBuffer;
    {
        auto surface = adoptCF(IOSurfaceLookupFromMachPort(sendRight->sendRight()));
        if (!surface)
            return std::nullopt;
        CVPixelBufferRef rawBuffer = nullptr;
        auto status = WebCore::CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface.get(), nullptr, &rawBuffer);
        if (status != noErr || !rawBuffer)
            return std::nullopt;
        pixelBuffer = adoptCF(rawBuffer);
    }
    return pixelBuffer;
}

#endif

} // namespace IPC
