/*
 * Copyright (C) 2014-2018 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. ``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
 * 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 "WebAVPlayerController.h"

#if PLATFORM(COCOA) && HAVE(AVKIT)

#import "Logging.h"
#import "PlaybackSessionInterfaceAVKit.h"
#import "PlaybackSessionModel.h"
#import "TimeRanges.h"
#import <AVFoundation/AVTime.h>
#import <pal/spi/cocoa/AVKitSPI.h>
#import <wtf/text/CString.h>
#import <wtf/text/WTFString.h>

#import <pal/cf/CoreMediaSoftLink.h>

SOFTLINK_AVKIT_FRAMEWORK()
SOFT_LINK_CLASS_OPTIONAL(AVKit, AVPlayerController)
SOFT_LINK_CLASS_OPTIONAL(AVKit, AVValueTiming)

OBJC_CLASS AVAssetTrack;
OBJC_CLASS AVMetadataItem;

using namespace WebCore;

static void * WebAVPlayerControllerSeekableTimeRangesObserverContext = &WebAVPlayerControllerSeekableTimeRangesObserverContext;
static void * WebAVPlayerControllerHasLiveStreamingContentObserverContext = &WebAVPlayerControllerHasLiveStreamingContentObserverContext;
static void * WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext = &WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext;

static double WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta = 3.0; // Minimum delta of time required to change the duration of the seekable time range.
static double WebAVPlayerControllerLiveStreamMinimumTargetDuration = 1.0; // Minimum segment duration to be considered valid.
static double WebAVPlayerControllerLiveStreamSeekableTimeRangeMinimumDuration = 30.0;

@implementation WebAVPlayerController {
    WeakPtr<WebCore::PlaybackSessionModel> _delegate;
    WeakPtr<WebCore::PlaybackSessionInterfaceAVKit> _playbackSessionInterface;
    double _defaultPlaybackRate;
    double _rate;
    BOOL _liveStreamEventModePossible;
    BOOL _isScrubbing;
    BOOL _allowsPictureInPicture;
    NSTimeInterval _seekToTime;
}

- (instancetype)init
{
    if (!getAVPlayerControllerClass()) {
        [self release];
        return nil;
    }

    if (!(self = [super init]))
        return self;

    initAVPlayerController();
    self.playerControllerProxy = adoptNS([allocAVPlayerControllerInstance() init]).get();
    _liveStreamEventModePossible = YES;

    [self addObserver:self forKeyPath:@"seekableTimeRanges" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
    [self addObserver:self forKeyPath:@"hasLiveStreamingContent" options:NSKeyValueObservingOptionInitial context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
    [self addObserver:self forKeyPath:@"playingOnSecondScreen" options:NSKeyValueObservingOptionNew context:WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext];

    return self;
}

- (void)dealloc
{
    [self removeObserver:self forKeyPath:@"seekableTimeRanges" context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
    [self removeObserver:self forKeyPath:@"hasLiveStreamingContent" context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
    [self removeObserver:self forKeyPath:@"playingOnSecondScreen" context:WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext];

    [_playerControllerProxy release];
    [_loadedTimeRanges release];
    [_seekableTimeRanges release];
    [_timing release];
    [_audioMediaSelectionOptions release];
    [_legibleMediaSelectionOptions release];
    [_currentAudioMediaSelectionOption release];
    [_currentLegibleMediaSelectionOption release];
    [_externalPlaybackAirPlayDeviceLocalizedName release];
    [_minTiming release];
    [_maxTiming release];
    [super dealloc];
}

- (AVPlayer *)player
{
    return nil;
}

- (id)forwardingTargetForSelector:(SEL)selector
{
    UNUSED_PARAM(selector);
    return self.playerControllerProxy;
}

- (void)play:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->play();
}

- (void)pause:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->pause();
}

- (void)togglePlayback:(id)sender
{
    UNUSED_PARAM(sender);
    if (!self.delegate)
        return;

    if (self.delegate->isPlaying())
        self.delegate->pause();
    else
        self.delegate->play();
}

- (void)togglePlaybackEvenWhenInBackground:(id)sender
{
    [self togglePlayback:sender];
}

- (BOOL)isPlaying
{
    return [self rate];
}

- (void)setPlaying:(BOOL)playing
{
    if (!self.delegate)
        return;
    if (playing)
        self.delegate->play();
    else
        self.delegate->pause();
}

- (WebCore::PlaybackSessionModel*)delegate
{
    return _delegate.get();
}

- (void)setDelegate:(WebCore::PlaybackSessionModel*)delegate
{
    _delegate = WeakPtr { delegate };
}

- (WebCore::PlaybackSessionInterfaceAVKit*)playbackSessionInterface
{
    return _playbackSessionInterface.get();
}

- (void)setPlaybackSessionInterface:(WebCore::PlaybackSessionInterfaceAVKit*)playbackSessionInterface
{
    _playbackSessionInterface = WeakPtr { playbackSessionInterface };
}

- (double)defaultPlaybackRate
{
    return _defaultPlaybackRate;
}

- (void)setDefaultPlaybackRate:(double)defaultPlaybackRate
{
    [self setDefaultPlaybackRate:defaultPlaybackRate fromJavaScript:NO];
}

- (void)setDefaultPlaybackRate:(double)defaultPlaybackRate fromJavaScript:(BOOL)fromJavaScript
{
    if (defaultPlaybackRate == _defaultPlaybackRate)
        return;

    [self willChangeValueForKey:@"defaultPlaybackRate"];
    _defaultPlaybackRate = defaultPlaybackRate;
    [self didChangeValueForKey:@"defaultPlaybackRate"];

    if (!fromJavaScript && self.delegate && self.delegate->defaultPlaybackRate() != _defaultPlaybackRate)
        self.delegate->setDefaultPlaybackRate(_defaultPlaybackRate);

    if ([self isPlaying])
        [self setRate:_defaultPlaybackRate fromJavaScript:fromJavaScript];
}

- (double)rate
{
    return _rate;
}

- (void)setRate:(double)rate
{
    [self setRate:rate fromJavaScript:NO];
}

- (void)setRate:(double)rate fromJavaScript:(BOOL)fromJavaScript
{
    if (rate == _rate)
        return;

    [self willChangeValueForKey:@"rate"];
    _rate = rate;
    [self didChangeValueForKey:@"rate"];

    // AVKit doesn't have a separate variable for "paused", instead representing it by a `rate` of
    // `0`. Unfortunately, `HTMLMediaElement::play` doesn't call `HTMLMediaElement::setPlaybackRate`
    // so if we propagate a `rate` of `0` along to the `HTMLMediaElement` then any attempt to
    // `HTMLMediaElement::play` will effectively be a no-op since the `playbackRate` will be `0`.
    if (!_rate)
        return;

    // In AVKit, the `defaultPlaybackRate` is used when playback starts, such as resuming after
    // pausing. In WebKit, however, `defaultPlaybackRate` is only used when first loading and after
    // ending scanning, with the `playbackRate` being used in all other cases, including when
    // resuming after pausing. As such, WebKit should return the `playbackRate` instead of the
    // `defaultPlaybackRate` in these cases when communicating with AVKit.
    [self setDefaultPlaybackRate:_rate fromJavaScript:fromJavaScript];

    if (!fromJavaScript && self.delegate && self.delegate->playbackRate() != _rate)
        self.delegate->setPlaybackRate(_rate);
}

+ (NSSet *)keyPathsForValuesAffectingPlaying
{
    return [NSSet setWithObject:@"rate"];
}

- (void)beginScrubbing:(id)sender
{
    UNUSED_PARAM(sender);
    _isScrubbing = YES;
    if (self.delegate)
        self.delegate->beginScrubbing();
}

- (void)endScrubbing:(id)sender
{
    UNUSED_PARAM(sender);
    _isScrubbing = NO;
    if (self.delegate)
        self.delegate->endScrubbing();
}

- (void)seekToTime:(NSTimeInterval)time
{
    _seekToTime = time;
    if (self.delegate)
        self.delegate->seekToTime(time);
}

- (void)seekToTime:(NSTimeInterval)time toleranceBefore:(NSTimeInterval)before toleranceAfter:(NSTimeInterval)after
{
    _seekToTime = time;
    if (self.delegate)
        self.delegate->seekToTime(time, before, after);
}

- (void)seekByTimeInterval:(NSTimeInterval)interval
{
    [self seekByTimeInterval:interval toleranceBefore:0. toleranceAfter:0.];
}

- (void)seekByTimeInterval:(NSTimeInterval)interval toleranceBefore:(NSTimeInterval)before toleranceAfter:(NSTimeInterval)after
{
    NSTimeInterval targetTime = [[self timing] currentValue] + interval;
    [self seekToTime:targetTime toleranceBefore:before toleranceAfter:after];
}

- (NSTimeInterval)currentTimeWithinEndTimes
{
    return self.timing.currentValue;
}

- (void)setCurrentTimeWithinEndTimes:(NSTimeInterval)currentTimeWithinEndTimes
{
    [self seekToTime:currentTimeWithinEndTimes];
}

+ (NSSet *)keyPathsForValuesAffectingCurrentTimeWithinEndTimes
{
    return [NSSet setWithObject:@"timing"];
}

- (BOOL)hasLiveStreamingContent
{
    if ([self status] == AVPlayerControllerStatusReadyToPlay)
        return [self contentDuration] == std::numeric_limits<float>::infinity();
    return NO;
}

+ (NSSet *)keyPathsForValuesAffectingHasLiveStreamingContent
{
    return [NSSet setWithObjects:@"contentDuration", @"status", nil];
}

- (NSTimeInterval)maxTime
{
    NSTimeInterval maxTime = NAN;

    NSTimeInterval duration = [self contentDuration];
    if (!isnan(duration) && !isinf(duration))
        maxTime = duration;
    else if ([self hasSeekableLiveStreamingContent] && [self maxTiming])
        maxTime = [[self maxTiming] currentValue];

    return maxTime;
}

+ (NSSet *)keyPathsForValuesAffectingMaxTime
{
    return [NSSet setWithObjects:@"contentDuration", @"hasSeekableLiveStreamingContent", @"maxTiming", nil];
}

- (NSTimeInterval)minTime
{
    NSTimeInterval minTime = 0.0;

    if ([self hasSeekableLiveStreamingContent] && [self minTiming])
        minTime = [[self minTiming] currentValue];

    return minTime;
}

+ (NSSet *)keyPathsForValuesAffectingMinTime
{
    return [NSSet setWithObjects:@"hasSeekableLiveStreamingContent", @"minTiming", nil];
}

- (void)skipBackwardThirtySeconds:(id)sender
{
    using namespace PAL;

    UNUSED_PARAM(sender);
    BOOL isTimeWithinSeekableTimeRanges = NO;
    CMTime currentTime = CMTimeMakeWithSeconds([[self timing] currentValue], 1000);
    CMTime thirtySecondsBeforeCurrentTime = CMTimeSubtract(currentTime, PAL::CMTimeMake(30, 1));

    for (NSValue *seekableTimeRangeValue in [self seekableTimeRanges]) {
        if (CMTimeRangeContainsTime([seekableTimeRangeValue CMTimeRangeValue], thirtySecondsBeforeCurrentTime)) {
            isTimeWithinSeekableTimeRanges = YES;
            break;
        }
    }

    if (isTimeWithinSeekableTimeRanges)
        [self seekToTime:CMTimeGetSeconds(thirtySecondsBeforeCurrentTime)];
}

- (void)gotoEndOfSeekableRanges:(id)sender
{
    using namespace PAL;

    UNUSED_PARAM(sender);
    NSTimeInterval timeAtEndOfSeekableTimeRanges = NAN;

    for (NSValue *seekableTimeRangeValue in [self seekableTimeRanges]) {
        CMTimeRange seekableTimeRange = [seekableTimeRangeValue CMTimeRangeValue];
        NSTimeInterval endOfSeekableTimeRange = CMTimeGetSeconds(CMTimeRangeGetEnd(seekableTimeRange));
        if (isnan(timeAtEndOfSeekableTimeRanges) || endOfSeekableTimeRange > timeAtEndOfSeekableTimeRanges)
            timeAtEndOfSeekableTimeRanges = endOfSeekableTimeRange;
    }

    if (!isnan(timeAtEndOfSeekableTimeRanges))
        [self seekToTime:timeAtEndOfSeekableTimeRanges];
}

- (BOOL)isScrubbing
{
    return _isScrubbing;
}

- (BOOL)isSeeking
{
    return _isScrubbing;
}

- (NSTimeInterval)seekToTime
{
    return _seekToTime;
}

- (BOOL)canScanForward
{
    return [self canPlay];
}

+ (NSSet *)keyPathsForValuesAffectingCanScanForward
{
    return [NSSet setWithObject:@"canPlay"];
}

- (void)beginScanningForward:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->beginScanningForward();
}

- (void)endScanningForward:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->endScanning();
}

- (void)beginScanningBackward:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->beginScanningBackward();
}

- (void)endScanningBackward:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->endScanning();
}

- (BOOL)canSeekToBeginning
{
    using namespace PAL;

    CMTime minimumTime = kCMTimeIndefinite;

    for (NSValue *value in [self seekableTimeRanges])
        minimumTime = CMTimeMinimum([value CMTimeRangeValue].start, minimumTime);

    return CMTIME_IS_NUMERIC(minimumTime);
}

+ (NSSet *)keyPathsForValuesAffectingCanSeekToBeginning
{
    return [NSSet setWithObject:@"seekableTimeRanges"];
}

- (void)seekToBeginning:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->seekToTime(-INFINITY);
}

- (void)seekChapterBackward:(id)sender
{
    [self seekToBeginning:sender];
}

- (BOOL)canSeekToEnd
{
    using namespace PAL;

    CMTime maximumTime = kCMTimeIndefinite;

    for (NSValue *value in [self seekableTimeRanges])
        maximumTime = CMTimeMaximum(CMTimeRangeGetEnd([value CMTimeRangeValue]), maximumTime);

    return CMTIME_IS_NUMERIC(maximumTime);
}

+ (NSSet *)keyPathsForValuesAffectingCanSeekToEnd
{
    return [NSSet setWithObject:@"seekableTimeRanges"];
}

- (void)seekToEnd:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->seekToTime(INFINITY);
}

- (void)seekChapterForward:(id)sender
{
    [self seekToEnd:sender];
}

- (BOOL)canSeekFrameBackward
{
    return NO;
}

- (BOOL)canSeekFrameForward
{
    return NO;
}

- (BOOL)hasMediaSelectionOptions
{
    return [self hasAudioMediaSelectionOptions] || [self hasLegibleMediaSelectionOptions];
}

+ (NSSet *)keyPathsForValuesAffectingHasMediaSelectionOptions
{
    return [NSSet setWithObjects:@"hasAudioMediaSelectionOptions", @"hasLegibleMediaSelectionOptions", nil];
}

- (BOOL)hasAudioMediaSelectionOptions
{
    return [[self audioMediaSelectionOptions] count] > 1;
}

+ (NSSet *)keyPathsForValuesAffectingHasAudioMediaSelectionOptions
{
    return [NSSet setWithObject:@"audioMediaSelectionOptions"];
}

- (BOOL)hasLegibleMediaSelectionOptions
{
    const NSUInteger numDefaultLegibleOptions = 2;
    return [[self legibleMediaSelectionOptions] count] > numDefaultLegibleOptions;
}

+ (NSSet *)keyPathsForValuesAffectingHasLegibleMediaSelectionOptions
{
    return [NSSet setWithObject:@"legibleMediaSelectionOptions"];
}

- (WebAVMediaSelectionOption *)currentAudioMediaSelectionOption
{
    return _currentAudioMediaSelectionOption;
}

- (void)setCurrentAudioMediaSelectionOption:(WebAVMediaSelectionOption *)option
{
    if (option == _currentAudioMediaSelectionOption)
        return;

    [_currentAudioMediaSelectionOption release];
    _currentAudioMediaSelectionOption = [option retain];

    if (!self.delegate)
        return;

    NSInteger index = NSNotFound;

    if (option && self.audioMediaSelectionOptions)
        index = [self.audioMediaSelectionOptions indexOfObject:option];

    if (index == NSNotFound)
        return;

    self.delegate->selectAudioMediaOption(index);
}

- (WebAVMediaSelectionOption *)currentLegibleMediaSelectionOption
{
    return _currentLegibleMediaSelectionOption;
}

- (void)setCurrentLegibleMediaSelectionOption:(WebAVMediaSelectionOption *)option
{
    if (option == _currentLegibleMediaSelectionOption)
        return;

    [_currentLegibleMediaSelectionOption release];
    _currentLegibleMediaSelectionOption = [option retain];

    if (!self.delegate)
        return;

    NSInteger index = NSNotFound;

    if (option && self.legibleMediaSelectionOptions)
        index = [self.legibleMediaSelectionOptions indexOfObject:option];

    if (index == NSNotFound)
        return;

    self.delegate->selectLegibleMediaOption(index);
}

- (BOOL)isPlayingOnExternalScreen
{
    return [self isExternalPlaybackActive] || [self isPlayingOnSecondScreen];
}

+ (NSSet *)keyPathsForValuesAffectingPlayingOnExternalScreen
{
    return [NSSet setWithObjects:@"externalPlaybackActive", @"playingOnSecondScreen", nil];
}

- (void)setAllowsPictureInPicture:(BOOL)allowsPictureInPicture
{
    _allowsPictureInPicture = allowsPictureInPicture;
}

- (BOOL)isPictureInPicturePossible
{
    return _allowsPictureInPicture && ![self isExternalPlaybackActive];
}

- (BOOL)isPictureInPictureInterrupted
{
    return _pictureInPictureInterrupted;
}

- (void)setPictureInPictureInterrupted:(BOOL)pictureInPictureInterrupted
{
    if (_pictureInPictureInterrupted != pictureInPictureInterrupted) {
        _pictureInPictureInterrupted = pictureInPictureInterrupted;
        if (pictureInPictureInterrupted)
            [self setPlaying:NO];
    }
}

- (BOOL)isMuted
{
    return _muted;
}

- (void)setMuted:(BOOL)muted
{
    if (_muted == muted)
        return;
    _muted = muted;

    if (self.delegate)
        self.delegate->setMuted(muted);
}

- (void)toggleMuted:(id)sender
{
    UNUSED_PARAM(sender);
    if (self.delegate)
        self.delegate->toggleMuted();
}

- (double)volume
{
    return self.delegate ? self.delegate->volume() : 0;
}

- (void)setVolume:(double)volume
{
    if (self.delegate)
        self.delegate->setVolume(volume);
}

- (void)volumeChanged:(double)volume
{
    UNUSED_PARAM(volume);
    [self willChangeValueForKey:@"volume"];
    [self didChangeValueForKey:@"volume"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    using namespace PAL;

    UNUSED_PARAM(object);
    UNUSED_PARAM(keyPath);

    if (WebAVPlayerControllerSeekableTimeRangesObserverContext == context) {
        NSArray *oldArray = change[NSKeyValueChangeOldKey];
        NSArray *newArray = change[NSKeyValueChangeNewKey];
        if ([oldArray isKindOfClass:[NSArray class]] && [newArray isKindOfClass:[NSArray class]]) {
            CMTimeRange oldSeekableTimeRange = [oldArray count] > 0 ? [[oldArray firstObject] CMTimeRangeValue] : kCMTimeRangeInvalid;
            CMTimeRange newSeekableTimeRange = [newArray count] > 0 ? [[newArray firstObject] CMTimeRangeValue] : kCMTimeRangeInvalid;
            if (!CMTimeRangeEqual(oldSeekableTimeRange, newSeekableTimeRange)) {
                if (CMTIMERANGE_IS_VALID(newSeekableTimeRange) && CMTIMERANGE_IS_VALID(oldSeekableTimeRange) && _liveStreamEventModePossible && !CMTimeRangeContainsTime(newSeekableTimeRange, oldSeekableTimeRange.start))
                    _liveStreamEventModePossible = NO;

                [self updateMinMaxTiming];
            }
        }
        return;
    }

    if (WebAVPlayerControllerHasLiveStreamingContentObserverContext == context) {
        [self updateMinMaxTiming];
        return;
    }

    if (WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext == context) {
        if (auto* delegate = self.delegate)
            delegate->setPlayingOnSecondScreen(_playingOnSecondScreen);
        return;
    }

    ASSERT_NOT_REACHED();
}

- (void)updateMinMaxTiming
{
    using namespace PAL;

    AVValueTiming *newMinTiming = nil;
    AVValueTiming *newMaxTiming = nil;

    // For live streams value timings for the min and max times are needed.
    if ([self hasLiveStreamingContent] && ([[self seekableTimeRanges] count] > 0)) {
        CMTimeRange seekableTimeRange = [[[self seekableTimeRanges] firstObject] CMTimeRangeValue];
        if (CMTIMERANGE_IS_VALID(seekableTimeRange)) {
            NSTimeInterval oldMinTime = [[self minTiming] currentValue];
            NSTimeInterval oldMaxTime = [[self maxTiming] currentValue];
            NSTimeInterval newMinTime = CMTimeGetSeconds(seekableTimeRange.start);
            NSTimeInterval newMaxTime = CMTimeGetSeconds(seekableTimeRange.start) + CMTimeGetSeconds(seekableTimeRange.duration) + (CACurrentMediaTime() - [self seekableTimeRangesLastModifiedTime]);
            double newMinTimingRate = _liveStreamEventModePossible ? 0.0 : 1.0;
            BOOL minTimingNeedsUpdate = YES;
            BOOL maxTimingNeedsUpdate = YES;

            if (isfinite([self liveUpdateInterval]) && [self liveUpdateInterval] > WebAVPlayerControllerLiveStreamMinimumTargetDuration) {
                // Only update the timing if the new time differs by one segment duration plus the hysteresis delta.
                minTimingNeedsUpdate = isnan(oldMinTime) || (fabs(oldMinTime - newMinTime) > [self liveUpdateInterval] + WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta) || ([[self minTiming] rate] != newMinTimingRate);
                maxTimingNeedsUpdate = isnan(oldMaxTime) || (fabs(oldMaxTime - newMaxTime) > [self liveUpdateInterval] + WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta);
            }

            if (minTimingNeedsUpdate || maxTimingNeedsUpdate) {
                newMinTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:newMinTime anchorTimeStamp:[getAVValueTimingClass() currentTimeStamp] rate:newMinTimingRate];
                newMaxTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:newMaxTime anchorTimeStamp:[getAVValueTimingClass() currentTimeStamp] rate:1.0];
            } else {
                newMinTiming = [self minTiming];
                newMaxTiming = [self maxTiming];
            }
        }
    }

    if (!newMinTiming)
        newMinTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:[self minTime] anchorTimeStamp:NAN rate:0.0];

    if (!newMaxTiming)
        newMaxTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:[self maxTime] anchorTimeStamp:NAN rate:0.0];

    [self setMinTiming:newMinTiming];
    [self setMaxTiming:newMaxTiming];
}

- (BOOL)hasSeekableLiveStreamingContent
{
    BOOL hasSeekableLiveStreamingContent = NO;

    if ([self hasLiveStreamingContent] && [self minTiming] && [self maxTiming] && isfinite([self liveUpdateInterval]) && [self liveUpdateInterval] > WebAVPlayerControllerLiveStreamMinimumTargetDuration && ([self seekableTimeRangesLastModifiedTime] != 0.0)) {
        NSTimeInterval timeStamp = [getAVValueTimingClass() currentTimeStamp];
        NSTimeInterval minTime = [[self minTiming] valueForTimeStamp:timeStamp];
        NSTimeInterval maxTime = [[self maxTiming] valueForTimeStamp:timeStamp];
        hasSeekableLiveStreamingContent = ((maxTime - minTime) > WebAVPlayerControllerLiveStreamSeekableTimeRangeMinimumDuration);
    }

    return hasSeekableLiveStreamingContent;
}

+ (NSSet *)keyPathsForValuesAffectingHasSeekableLiveStreamingContent
{
    return [NSSet setWithObjects:@"hasLiveStreamingContent", @"minTiming", @"maxTiming", @"seekableTimeRangesLastModifiedTime", nil];
}

@end

@implementation WebAVMediaSelectionOption {
    RetainPtr<NSString> _localizedDisplayName;
}

- (instancetype)initWithMediaType:(AVMediaType)mediaType displayName:(NSString *)displayName
{
    self = [super init];
    if (!self)
        return nil;

    _mediaType = mediaType;
    _localizedDisplayName = displayName;

    return self;
}

- (NSString *)localizedDisplayName
{
    return _localizedDisplayName.get();
}

- (NSArray<NSNumber *> *)mediaSubTypes
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption mediaSubTypes] unimplemented");
    return @[];
}

- (BOOL)hasMediaCharacteristic:(AVMediaCharacteristic)mediaCharacteristic
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption hasMediaCharacteristic:] unimplemented");
    return NO;
}

- (BOOL) isPlayable
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption isPlayable:] unimplemented");
    return YES;
}

- (NSString *)extendedLanguageTag
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption extendedLanguageTag] unimplemented");
    return nil;
}

- (NSLocale *)locale
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption locale] unimplemented");
    return nil;
}

- (NSArray<AVMetadataItem *> *)commonMetadata
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption commonMetadata] unimplemented");
    return @[];
}

- (NSArray<NSString *> *)availableMetadataFormats
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption availableMetadataFormats] unimplemented");
    return @[];
}

- (NSArray<AVMetadataItem *> *)metadataForFormat:(NSString *)format
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption metadataForFormat:] unimplemented");
    return @[];
}

- (AVMediaSelectionOption *)associatedMediaSelectionOptionInMediaSelectionGroup:(AVMediaSelectionGroup *)mediaSelectionGroup
{
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption associatedMediaSelectionOptionInMediaSelectionGroup] unimplemented");
    ASSERT_NOT_REACHED();
    return nil;
}

- (id)propertyList
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption propertyList] unimplemented");
    return @[];
}

- (NSString *)displayNameWithLocale:(NSLocale *)locale
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption displayNameWithLocale:] unimplemented");
    return nil;
}

- (NSArray<NSString *> *)mediaCharacteristics
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption mediaCharacteristics] unimplemented");
    return @[];
}

- (NSString *)outOfBandSource
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption outOfBandSource] unimplemented");
    return nil;
}

- (NSString *)outOfBandIdentifier
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption outOfBandIdentifier] unimplemented");
    return nil;
}

- (BOOL)_isDesignatedDefault
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption _isDesignatedDefault] unimplemented");
    return NO;
}

- (NSString *)languageCode
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption languageCode] unimplemented");
    return nil;
}

- (AVAssetTrack *)track
{
    ASSERT_NOT_REACHED();
    WTFLogAlways("ERROR: -[WebAVMediaSelectionOption track:] unimplemented");
    return nil;
}

@end

#endif // PLATFORM(COCOA) && HAVE(AVKIT)

