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

#pragma once

#if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)

#include "IntSizeHash.h"
#include "OrientationNotifier.h"
#include "RealtimeVideoSource.h"
#include <wtf/Lock.h>
#include <wtf/text/StringHash.h>

typedef struct opaqueCMSampleBuffer* CMSampleBufferRef;

OBJC_CLASS AVCaptureConnection;
OBJC_CLASS AVCaptureDevice;
OBJC_CLASS AVCaptureDeviceFormat;
OBJC_CLASS AVCaptureOutput;
OBJC_CLASS AVCaptureSession;
OBJC_CLASS AVCaptureVideoDataOutput;
OBJC_CLASS AVFrameRateRange;
OBJC_CLASS NSError;
OBJC_CLASS NSNotification;
OBJC_CLASS WebCoreAVVideoCaptureSourceObserver;

namespace WebCore {

class AVVideoPreset;
class ImageTransferSessionVT;

class AVVideoCaptureSource : public RealtimeVideoSource, private OrientationNotifier::Observer {
public:
    static CaptureSourceOrError create(String&& id, String&& hashSalt, const MediaConstraints*);

    WEBCORE_EXPORT static VideoCaptureFactory& factory();

    enum class InterruptionReason { None, VideoNotAllowedInBackground, AudioInUse, VideoInUse, VideoNotAllowedInSideBySide };
    void captureSessionBeginInterruption(RetainPtr<NSNotification>);
    void captureSessionEndInterruption(RetainPtr<NSNotification>);
    void deviceDisconnected(RetainPtr<NSNotification>);

    AVCaptureSession* session() const { return m_session.get(); }

    void captureSessionIsRunningDidChange(bool);
    void captureSessionRuntimeError(RetainPtr<NSError>);
    void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*);
    void captureDeviceSuspendedDidChange();

private:
    AVVideoCaptureSource(AVCaptureDevice*, String&& id, String&& hashSalt);
    virtual ~AVVideoCaptureSource();

    void clearSession();

    bool setupSession();
    bool setupCaptureSession();
    void shutdownCaptureSession();

    const RealtimeMediaSourceCapabilities& capabilities() final;
    const RealtimeMediaSourceSettings& settings() final;
    void startProducingData() final;
    void stopProducingData() final;
    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
    void monitorOrientation(OrientationNotifier&) final;
    void beginConfiguration() final;
    void commitConfiguration() final;
    bool isCaptureSource() const final { return true; }
    CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Camera; }
    bool interrupted() const final;

    void setFrameRateWithPreset(double, RefPtr<VideoPreset>) final;
    bool prefersPreset(VideoPreset&) final;
    void generatePresets() final;
    bool canResizeVideoFrames() const final { return true; }

    void setSessionSizeAndFrameRate();
    bool setPreset(NSString*);
    void computeSampleRotation();
    AVFrameRateRange* frameDurationForFrameRate(double);

    // OrientationNotifier::Observer API
    void orientationChanged(int orientation) final;

    bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);

    void processNewFrame(Ref<MediaSample>&&);
    IntSize sizeForPreset(NSString*);

    AVCaptureDevice* device() const { return m_device.get(); }

#if !RELEASE_LOG_DISABLED
    const char* logClassName() const override { return "AVVideoCaptureSource"; }
#endif

    RefPtr<MediaSample> m_buffer;
    RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
    std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;

    int m_sensorOrientation { 0 };
    int m_deviceOrientation { 0 };
    MediaSample::VideoRotation m_sampleRotation { MediaSample::VideoRotation::None };

    Optional<RealtimeMediaSourceSettings> m_currentSettings;
    Optional<RealtimeMediaSourceCapabilities> m_capabilities;
    RetainPtr<WebCoreAVVideoCaptureSourceObserver> m_objcObserver;
    RetainPtr<AVCaptureSession> m_session;
    RetainPtr<AVCaptureDevice> m_device;

    Lock m_presetMutex;
    RefPtr<AVVideoPreset> m_currentPreset;
    IntSize m_currentSize;
    double m_currentFrameRate;
    InterruptionReason m_interruption { InterruptionReason::None };
    int m_framesToDropAtStartup { 0 };
    bool m_isRunning { false };
};

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::AVVideoPreset)
    static bool isType(const WebCore::VideoPreset& preset) { return preset.type == WebCore::VideoPreset::VideoPresetType::AVCapture; }
SPECIALIZE_TYPE_TRAITS_END()

#endif // ENABLE(MEDIA_STREAM)
