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

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

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

#import <pal/cf/CoreMediaSoftLink.h>
#import <pal/cocoa/AVFoundationSoftLink.h>

SOFTLINK_AVKIT_FRAMEWORK()
SOFT_LINK_CLASS_OPTIONAL(AVKit, AVValueTiming)

namespace WebCore {

PlaybackSessionInterfaceAVKit::PlaybackSessionInterfaceAVKit(PlaybackSessionModel& model)
    : m_playerController(adoptNS([[WebAVPlayerController alloc] init]))
    , m_playbackSessionModel(&model)
{
    ASSERT(isUIThread());
    model.addClient(*this);
    [m_playerController setPlaybackSessionInterface:this];
    [m_playerController setDelegate:&model];

    durationChanged(model.duration());
    currentTimeChanged(model.currentTime(), [[NSProcessInfo processInfo] systemUptime]);
    bufferedTimeChanged(model.bufferedTime());
    OptionSet<PlaybackSessionModel::PlaybackState> playbackState;
    if (model.isPlaying())
        playbackState.add(PlaybackSessionModel::PlaybackState::Playing);
    if (model.isStalled())
        playbackState.add(PlaybackSessionModel::PlaybackState::Stalled);
    rateChanged(playbackState, model.playbackRate(), model.defaultPlaybackRate());
    seekableRangesChanged(model.seekableRanges(), model.seekableTimeRangesLastModifiedTime(), model.liveUpdateInterval());
    canPlayFastReverseChanged(model.canPlayFastReverse());
    audioMediaSelectionOptionsChanged(model.audioMediaSelectionOptions(), model.audioMediaSelectedIndex());
    legibleMediaSelectionOptionsChanged(model.legibleMediaSelectionOptions(), model.legibleMediaSelectedIndex());
    externalPlaybackChanged(model.externalPlaybackEnabled(), model.externalPlaybackTargetType(), model.externalPlaybackLocalizedDeviceName());
    wirelessVideoPlaybackDisabledChanged(model.wirelessVideoPlaybackDisabled());
}

PlaybackSessionInterfaceAVKit::~PlaybackSessionInterfaceAVKit()
{
    ASSERT(isUIThread());
    [m_playerController setPlaybackSessionInterface:nullptr];
    [m_playerController setExternalPlaybackActive:false];

    invalidate();
}

PlaybackSessionModel* PlaybackSessionInterfaceAVKit::playbackSessionModel() const
{
    return m_playbackSessionModel;
}

void PlaybackSessionInterfaceAVKit::durationChanged(double duration)
{
    WebAVPlayerController* playerController = m_playerController.get();

    playerController.contentDuration = duration;
    playerController.contentDurationWithinEndTimes = duration;

    // FIXME: we take this as an indication that playback is ready.
    playerController.canPlay = YES;
    playerController.canPause = YES;
    playerController.canTogglePlayback = YES;
    playerController.hasEnabledAudio = YES;
    playerController.canSeek = YES;
    playerController.status = AVPlayerControllerStatusReadyToPlay;
}

void PlaybackSessionInterfaceAVKit::currentTimeChanged(double currentTime, double anchorTime)
{
    if ([m_playerController isScrubbing])
        return;

    NSTimeInterval anchorTimeStamp = ![m_playerController rate] ? NAN : anchorTime;
    AVValueTiming *timing = [getAVValueTimingClass() valueTimingWithAnchorValue:currentTime
        anchorTimeStamp:anchorTimeStamp rate:0];

    [m_playerController setTiming:timing];
}

void PlaybackSessionInterfaceAVKit::bufferedTimeChanged(double bufferedTime)
{
    WebAVPlayerController* playerController = m_playerController.get();
    double duration = playerController.contentDuration;
    double normalizedBufferedTime;
    if (!duration)
        normalizedBufferedTime = 0;
    else
        normalizedBufferedTime = bufferedTime / duration;
    playerController.loadedTimeRanges = @[@0, @(normalizedBufferedTime)];
}

void PlaybackSessionInterfaceAVKit::rateChanged(OptionSet<PlaybackSessionModel::PlaybackState> playbackState, double playbackRate, double defaultPlaybackRate)
{
    [m_playerController setDefaultPlaybackRate:defaultPlaybackRate fromJavaScript:YES];
    if (!playbackState.contains(PlaybackSessionModel::PlaybackState::Stalled))
        [m_playerController setRate:playbackState.contains(PlaybackSessionModel::PlaybackState::Playing) ? playbackRate : 0. fromJavaScript:YES];
}

void PlaybackSessionInterfaceAVKit::seekableRangesChanged(const TimeRanges& timeRanges, double lastModifiedTime, double liveUpdateInterval)
{
    RetainPtr<NSMutableArray> seekableRanges = adoptNS([[NSMutableArray alloc] init]);

#if !PLATFORM(WATCHOS)
    for (unsigned i = 0; i < timeRanges.length(); i++) {
        double start = timeRanges.start(i).releaseReturnValue();
        double end = timeRanges.end(i).releaseReturnValue();

        CMTimeRange range = PAL::CMTimeRangeMake(PAL::CMTimeMakeWithSeconds(start, 1000), PAL::CMTimeMakeWithSeconds(end-start, 1000));
        [seekableRanges addObject:[NSValue valueWithCMTimeRange:range]];
    }
#else
    UNUSED_PARAM(timeRanges);
#endif

    [m_playerController setSeekableTimeRanges:seekableRanges.get()];
    [m_playerController setSeekableTimeRangesLastModifiedTime: lastModifiedTime];
    [m_playerController setLiveUpdateInterval:liveUpdateInterval];
}

void PlaybackSessionInterfaceAVKit::canPlayFastReverseChanged(bool canPlayFastReverse)
{
    [m_playerController setCanScanBackward:canPlayFastReverse];
}

static AVMediaType toAVMediaType(MediaSelectionOption::MediaType type)
{
    switch (type) {
    case MediaSelectionOption::MediaType::Audio:
        return AVMediaTypeAudio;
        break;
    case MediaSelectionOption::MediaType::Subtitles:
        return AVMediaTypeSubtitle;
        break;
    case MediaSelectionOption::MediaType::Captions:
        return AVMediaTypeClosedCaption;
        break;
    case MediaSelectionOption::MediaType::Metadata:
        return AVMediaTypeMetadata;
        break;
    case MediaSelectionOption::MediaType::Unknown:
        ASSERT_NOT_REACHED();
        break;
    }

    return AVMediaTypeMetadata;
}

static RetainPtr<NSArray> mediaSelectionOptions(const Vector<MediaSelectionOption>& options)
{
    return createNSArray(options, [] (auto& option) {
        return adoptNS([[WebAVMediaSelectionOption alloc] initWithMediaType:toAVMediaType(option.mediaType) displayName:option.displayName]);
    });
}

void PlaybackSessionInterfaceAVKit::audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex)
{
    auto webOptions = mediaSelectionOptions(options);
    [m_playerController setAudioMediaSelectionOptions:webOptions.get()];
    if (selectedIndex < [webOptions count])
        [m_playerController setCurrentAudioMediaSelectionOption:[webOptions objectAtIndex:static_cast<NSUInteger>(selectedIndex)]];
}

void PlaybackSessionInterfaceAVKit::legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex)
{
    auto webOptions = mediaSelectionOptions(options);
    [m_playerController setLegibleMediaSelectionOptions:webOptions.get()];
    if (selectedIndex < [webOptions count])
        [m_playerController setCurrentLegibleMediaSelectionOption:[webOptions objectAtIndex:static_cast<NSUInteger>(selectedIndex)]];
}

void PlaybackSessionInterfaceAVKit::externalPlaybackChanged(bool enabled, PlaybackSessionModel::ExternalPlaybackTargetType targetType, const String& localizedDeviceName)
{
    AVPlayerControllerExternalPlaybackType externalPlaybackType = AVPlayerControllerExternalPlaybackTypeNone;
    if (enabled && targetType == PlaybackSessionModel::TargetTypeAirPlay)
        externalPlaybackType = AVPlayerControllerExternalPlaybackTypeAirPlay;
    else if (enabled && targetType == PlaybackSessionModel::TargetTypeTVOut)
        externalPlaybackType = AVPlayerControllerExternalPlaybackTypeTVOut;

    WebAVPlayerController* playerController = m_playerController.get();
    playerController.externalPlaybackAirPlayDeviceLocalizedName = localizedDeviceName;
    playerController.externalPlaybackType = externalPlaybackType;
    playerController.externalPlaybackActive = enabled;
}

void PlaybackSessionInterfaceAVKit::wirelessVideoPlaybackDisabledChanged(bool disabled)
{
    [m_playerController setAllowsExternalPlayback:!disabled];
}

void PlaybackSessionInterfaceAVKit::mutedChanged(bool muted)
{
    [m_playerController setMuted:muted];
}

void PlaybackSessionInterfaceAVKit::volumeChanged(double volume)
{
    [m_playerController volumeChanged:volume];
}

void PlaybackSessionInterfaceAVKit::invalidate()
{
    if (!m_playbackSessionModel)
        return;

    [m_playerController setDelegate:nullptr];
    m_playbackSessionModel->removeClient(*this);
    m_playbackSessionModel = nullptr;
}

void PlaybackSessionInterfaceAVKit::modelDestroyed()
{
    ASSERT(isUIThread());
    invalidate();
    ASSERT(!m_playbackSessionModel);
}

}

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