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

#include "config.h"
#include "ReplayKitCaptureSource.h"

#if ENABLE(MEDIA_STREAM) && PLATFORM(IOS)

#import "Logging.h"
#import "RealtimeVideoUtilities.h"
#import <wtf/BlockPtr.h>
#import <wtf/NeverDestroyed.h>
#import <wtf/UUID.h>
#import <wtf/text/StringToIntegerConversion.h>

#import <pal/cf/CoreMediaSoftLink.h>
#import <pal/ios/ReplayKitSoftLink.h>

using namespace WebCore;
@interface WebCoreReplayKitScreenRecorderHelper : NSObject {
    WeakPtr<ReplayKitCaptureSource> _callback;
}

- (instancetype)initWithCallback:(WeakPtr<ReplayKitCaptureSource>&&)callback;
- (void)disconnect;
- (void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context;
@end

@implementation WebCoreReplayKitScreenRecorderHelper
- (instancetype)initWithCallback:(WeakPtr<ReplayKitCaptureSource>&&)callback
{
    self = [super init];
    if (!self)
        return self;

    _callback = WTFMove(callback);
    [[PAL::getRPScreenRecorderClass() sharedRecorder] addObserver:self forKeyPath:@"recording" options:NSKeyValueObservingOptionNew context:(void *)nil];

    return self;
}

- (void)disconnect
{
    _callback = nullptr;
    [[PAL::getRPScreenRecorderClass() sharedRecorder] removeObserver:self forKeyPath:@"recording"];
}

- (void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
    UNUSED_PARAM(object);
    UNUSED_PARAM(context);

    if (!_callback)
        return;

    id newValue = [change valueForKey:NSKeyValueChangeNewKey];
    bool willChange = [[change valueForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue];

#if !RELEASE_LOG_DISABLED
    if (_callback->loggerPtr()) {
        auto identifier = Logger::LogSiteIdentifier("ReplayKitCaptureSource", "observeValueForKeyPath", _callback->logIdentifier());
        RetainPtr<NSString> valueString = adoptNS([[NSString alloc] initWithFormat:@"%@", newValue]);
        _callback->logger().logAlways(_callback->logChannel(), identifier, willChange ? "will" : "did", " change '", [keyPath UTF8String], "' to ", [valueString.get() UTF8String]);
    }
#endif

    if (willChange)
        return;

    if ([keyPath isEqualToString:@"recording"])
        _callback->captureStateDidChange();
}
@end

namespace WebCore {

bool ReplayKitCaptureSource::isAvailable()
{
    return [PAL::getRPScreenRecorderClass() sharedRecorder].isAvailable;
}

Expected<UniqueRef<DisplayCaptureSourceCocoa::Capturer>, String> ReplayKitCaptureSource::create(const String&)
{
    if (!isAvailable())
        return makeUnexpected("Screen capture unavailable"_s);

    return UniqueRef<DisplayCaptureSourceCocoa::Capturer>(makeUniqueRef<ReplayKitCaptureSource>());
}

ReplayKitCaptureSource::ReplayKitCaptureSource()
    : m_captureWatchdogTimer(*this, &ReplayKitCaptureSource::verifyCaptureIsActive)
{
}

ReplayKitCaptureSource::~ReplayKitCaptureSource()
{
    [m_recorderHelper disconnect];
    stop();
    m_currentFrame = nullptr;
}

bool ReplayKitCaptureSource::start()
{
    ASSERT(isAvailable());

    auto identifier = LOGIDENTIFIER;
    ALWAYS_LOG_IF(loggerPtr(), identifier);

    auto *screenRecorder = [PAL::getRPScreenRecorderClass() sharedRecorder];
    if (screenRecorder.recording)
        return true;

    // FIXME: Add support for concurrent audio capture.
    [screenRecorder setMicrophoneEnabled:NO];

    if (!m_recorderHelper)
        m_recorderHelper = ([[WebCoreReplayKitScreenRecorderHelper alloc] initWithCallback:this]);

    auto captureHandler = makeBlockPtr([this, weakThis = WeakPtr { *this }, identifier](CMSampleBufferRef _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) {

        if (bufferType != RPSampleBufferTypeVideo)
            return;

        ERROR_LOG_IF(error && loggerPtr(), identifier, "startCaptureWithHandler failed ", [error localizedDescription].UTF8String);

        ++m_frameCount;

        RunLoop::main().dispatch([weakThis, sampleBuffer = retainPtr(sampleBuffer)]() mutable {
            if (!weakThis)
                return;

            weakThis->screenRecorderDidOutputVideoSample(WTFMove(sampleBuffer));
        });
    });

    auto completionHandler = makeBlockPtr([this, weakThis = WeakPtr { *this }, identifier](NSError * _Nullable error) {
        // FIXME: It should be safe to call `videoSampleAvailable` from any thread. Test this and get rid of this main thread hop.
        RunLoop::main().dispatch([this, weakThis, error = retainPtr(error), identifier]() mutable {
            if (!weakThis || !error)
                return;

            ERROR_LOG_IF(loggerPtr(), identifier, "completionHandler failed ", [error localizedDescription].UTF8String);
            weakThis->stop();
        });
    });

    [screenRecorder startCaptureWithHandler:captureHandler.get() completionHandler:completionHandler.get()];

    return true;
}

void ReplayKitCaptureSource::screenRecorderDidOutputVideoSample(RetainPtr<CMSampleBufferRef>&& sampleBuffer)
{
    m_currentFrame = sampleBuffer.get();
    m_intrinsicSize = IntSize(PAL::CMVideoFormatDescriptionGetPresentationDimensions(PAL::CMSampleBufferGetFormatDescription(m_currentFrame.get()), true, true));
}

void ReplayKitCaptureSource::captureStateDidChange()
{
    RunLoop::main().dispatch([this, weakThis = WeakPtr { *this }, identifier = LOGIDENTIFIER]() mutable {
        if (!weakThis)
            return;

        bool isRecording = !![[PAL::getRPScreenRecorderClass() sharedRecorder] isRecording];
        if (m_isRunning == (isRecording && !m_interrupted))
            return;

        m_isRunning = isRecording && !m_interrupted;
        ALWAYS_LOG_IF(loggerPtr(), identifier, m_isRunning);
        capturerIsRunningChanged(m_isRunning);
    });
}

void ReplayKitCaptureSource::stop()
{
    auto identifier = LOGIDENTIFIER;
    ALWAYS_LOG_IF(loggerPtr(), identifier);
    m_captureWatchdogTimer.stop();
    m_interrupted = false;
    m_isRunning = false;

    auto *screenRecorder = [PAL::getRPScreenRecorderClass() sharedRecorder];
    if (screenRecorder.recording) {
        [screenRecorder stopCaptureWithHandler:^(NSError * _Nullable error) {
            ERROR_LOG_IF(error && loggerPtr(), identifier, "startCaptureWithHandler failed ", [error localizedDescription].UTF8String);
        }];
    }
}

DisplayCaptureSourceCocoa::DisplayFrameType ReplayKitCaptureSource::generateFrame()
{
    return m_currentFrame;
}

void ReplayKitCaptureSource::verifyCaptureIsActive()
{
    ASSERT(m_isRunning || m_interrupted);
    auto identifier = LOGIDENTIFIER;
    if (m_lastFrameCount != m_frameCount) {
        m_lastFrameCount = m_frameCount;
        if (m_interrupted) {
            ALWAYS_LOG_IF(loggerPtr(), identifier, "frame received after interruption, unmuting");
            m_interrupted = false;
            captureStateDidChange();
        }
        return;
    }

    ALWAYS_LOG_IF(loggerPtr(), identifier, "no frame received in ", static_cast<int>(m_captureWatchdogTimer.repeatInterval().value()), " seconds, muting");
    m_interrupted = true;
    captureStateDidChange();
}

void ReplayKitCaptureSource::startCaptureWatchdogTimer()
{
    static constexpr Seconds verifyCaptureInterval = 2_s;
    if (m_captureWatchdogTimer.isActive())
        return;

    m_captureWatchdogTimer.startRepeating(verifyCaptureInterval);
    m_lastFrameCount = m_frameCount;
}

static String screenDeviceUUID()
{
    static NeverDestroyed<String> screenID = createCanonicalUUIDString();
    return screenID;
}

static CaptureDevice& screenDevice()
{
    static NeverDestroyed<CaptureDevice> device = { screenDeviceUUID(), CaptureDevice::DeviceType::Screen, makeString("Screen 1"), emptyString(), true };
    return device;
}

std::optional<CaptureDevice> ReplayKitCaptureSource::screenCaptureDeviceWithPersistentID(const String& displayID)
{
    if (!isAvailable()) {
        RELEASE_LOG_ERROR(WebRTC, "ReplayKitCaptureSource::screenCaptureDeviceWithPersistentID: screen capture unavailable");
        return std::nullopt;
    }

    if (displayID != screenDeviceUUID()) {
        RELEASE_LOG_ERROR(WebRTC, "ReplayKitCaptureSource::screenCaptureDeviceWithPersistentID: invalid display ID");
        return std::nullopt;
    }

    return screenDevice();
}

void ReplayKitCaptureSource::screenCaptureDevices(Vector<CaptureDevice>& displays)
{
    if (isAvailable())
        displays.append(screenDevice());
}

} // namespace WebCore

#endif // ENABLE(MEDIA_STREAM) && PLATFORM(IOS)
