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

#pragma once

#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "api/video/encoded_image.h"
#include "modules/include/module_common_types.h"

using CVPixelBufferRef = struct __CVBuffer*;

namespace webrtc {

class EncodedImageCallback;
class VideoCodec;
class VideoFrame;
struct SdpVideoFormat;
class Settings;

class VideoEncoderFactoryWithSimulcast final : public VideoEncoderFactory {
public:
    explicit VideoEncoderFactoryWithSimulcast(std::unique_ptr<VideoEncoderFactory>&& factory)
        : m_internalEncoderFactory(std::move(factory))
    {
    }

    VideoEncoderFactory::CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const final { return m_internalEncoderFactory->QueryVideoEncoder(format); }

    std::unique_ptr<VideoEncoder> CreateVideoEncoder(const SdpVideoFormat& format) final;
 
    std::vector<SdpVideoFormat> GetSupportedFormats() const final { return m_internalEncoderFactory->GetSupportedFormats(); }

private:
    const std::unique_ptr<VideoEncoderFactory> m_internalEncoderFactory;
};

using WebKitVideoEncoder = void*;
using VideoEncoderCreateCallback = WebKitVideoEncoder(*)(const SdpVideoFormat& format);
using VideoEncoderReleaseCallback = int32_t(*)(WebKitVideoEncoder);
using VideoEncoderInitializeCallback = int32_t(*)(WebKitVideoEncoder, const VideoCodec&);
using VideoEncoderEncodeCallback = int32_t(*)(WebKitVideoEncoder, const VideoFrame&, bool shouldEncodeAsKeyFrame);
using VideoEncoderRegisterEncodeCompleteCallback = int32_t(*)(WebKitVideoEncoder, void* encodedImageCallback);
using VideoEncoderSetRatesCallback = void(*)(WebKitVideoEncoder, const VideoEncoder::RateControlParameters&);

void setVideoEncoderCallbacks(VideoEncoderCreateCallback, VideoEncoderReleaseCallback, VideoEncoderInitializeCallback, VideoEncoderEncodeCallback, VideoEncoderRegisterEncodeCompleteCallback, VideoEncoderSetRatesCallback);

using WebKitEncodedFrameTiming = EncodedImage::Timing;
struct WebKitEncodedFrameInfo {
    uint32_t width { 0 };
    uint32_t height { 0 };
    int64_t timeStamp { 0 };
    int64_t ntpTimeMS { 0 };
    int64_t captureTimeMS { 0 };
    VideoFrameType frameType { VideoFrameType::kVideoFrameDelta };
    VideoRotation rotation { kVideoRotation_0 };
    VideoContentType contentType { VideoContentType::UNSPECIFIED };
    bool completeFrame = false;
    int qp { -1 };
    WebKitEncodedFrameTiming timing;

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static bool decode(Decoder&, WebKitEncodedFrameInfo&);
};

class WebKitRTPFragmentationHeader {
public:
    explicit WebKitRTPFragmentationHeader(webrtc::RTPFragmentationHeader* = nullptr);

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static bool decode(Decoder&, WebKitRTPFragmentationHeader&);

    webrtc::RTPFragmentationHeader* value() { return m_value; };

private:
    webrtc::RTPFragmentationHeader* m_value { nullptr };
    std::unique_ptr<webrtc::RTPFragmentationHeader> m_ownedHeader;
};

class RemoteVideoEncoder final : public webrtc::VideoEncoder {
public:
    explicit RemoteVideoEncoder(WebKitVideoEncoder);
    ~RemoteVideoEncoder() = default;

    static void encodeComplete(void* callback, uint8_t* buffer, size_t length, const WebKitEncodedFrameInfo&, const webrtc::RTPFragmentationHeader*);

private:
    int32_t InitEncode(const VideoCodec*, const Settings&) final;
    int32_t RegisterEncodeCompleteCallback(EncodedImageCallback*) final;
    int32_t Release() final;
    int32_t Encode(const VideoFrame&, const std::vector<VideoFrameType>*) final;
    void SetRates(const RateControlParameters&) final;
    EncoderInfo GetEncoderInfo() const final;

    WebKitVideoEncoder m_internalEncoder;
};

using LocalEncoder = void*;
using LocalEncoderCallback = void (^)(const uint8_t* buffer, size_t size, const webrtc::WebKitEncodedFrameInfo&, webrtc::RTPFragmentationHeader*);
void* createLocalEncoder(const webrtc::SdpVideoFormat&, LocalEncoderCallback);
void releaseLocalEncoder(LocalEncoder);
void initializeLocalEncoder(LocalEncoder, uint16_t width, uint16_t height, unsigned int startBitrate, unsigned int maxBitrate, unsigned int minBitrate, uint32_t maxFramerate);
void encodeLocalEncoderFrame(LocalEncoder, CVPixelBufferRef, int64_t timeStamp, webrtc::VideoRotation, bool isKeyframeRequired);
void setLocalEncoderRates(LocalEncoder, uint32_t bitRate, uint32_t frameRate);

template<class Decoder>
bool WebKitEncodedFrameInfo::decode(Decoder& decoder, WebKitEncodedFrameInfo& info)
{
    if (!decoder.decode(info.width))
        return false;
    if (!decoder.decode(info.height))
        return false;
    if (!decoder.decode(info.timeStamp))
        return false;
    if (!decoder.decode(info.ntpTimeMS))
        return false;
    if (!decoder.decode(info.captureTimeMS))
        return false;
    if (!decoder.decodeEnum(info.frameType))
        return false;
    if (!decoder.decodeEnum(info.rotation))
        return false;
    if (!decoder.decodeEnum(info.contentType))
        return false;
    if (!decoder.decode(info.completeFrame))
        return false;
    if (!decoder.decode(info.qp))
        return false;

    if (!decoder.decode(info.timing.flags))
        return false;

    if (!decoder.decode(info.timing.encode_start_ms))
        return false;

    if (!decoder.decode(info.timing.encode_finish_ms))
        return false;

    if (!decoder.decode(info.timing.packetization_finish_ms))
        return false;

    if (!decoder.decode(info.timing.pacer_exit_ms))
        return false;

    if (!decoder.decode(info.timing.network_timestamp_ms))
        return false;

    if (!decoder.decode(info.timing.network2_timestamp_ms))
        return false;

    if (!decoder.decode(info.timing.receive_start_ms))
        return false;

    return true;
}

template<class Encoder>
void WebKitEncodedFrameInfo::encode(Encoder& encoder) const
{
    encoder << width;
    encoder << height;
    encoder << timeStamp;
    encoder << ntpTimeMS;
    encoder << captureTimeMS;
    encoder.encodeEnum(frameType);
    encoder.encodeEnum(rotation);
    encoder.encodeEnum(contentType);
    encoder << completeFrame;
    encoder << qp;

    encoder << timing.flags;
    encoder << timing.encode_start_ms;
    encoder << timing.encode_finish_ms;
    encoder << timing.packetization_finish_ms;
    encoder << timing.pacer_exit_ms;
    encoder << timing.network_timestamp_ms;
    encoder << timing.network2_timestamp_ms;
    encoder << timing.receive_start_ms;
    encoder << timing.receive_finish_ms;
}

inline WebKitRTPFragmentationHeader::WebKitRTPFragmentationHeader(webrtc::RTPFragmentationHeader* header)
    : m_value(header)
{
}

template<class Encoder>
void WebKitRTPFragmentationHeader::encode(Encoder& encoder) const
{
    encoder << !!m_value;
    if (!m_value)
        return;
    encoder << static_cast<unsigned>(m_value->Size());
    for (unsigned i = 0; i < m_value->Size(); ++i) {
        encoder << static_cast<unsigned>(m_value->Offset(i));
        encoder << static_cast<unsigned>(m_value->Length(i));
    }
}

template<class Decoder>
bool WebKitRTPFragmentationHeader::decode(Decoder& decoder, WebKitRTPFragmentationHeader& header)
{
    bool isNull;
    if (!decoder.decode(isNull))
        return false;
    
    if (isNull) {
        header.m_value = nullptr;
        return true;
    }

    unsigned size;
    if (!decoder.decode(size))
        return false;

    header.m_ownedHeader = std::make_unique<webrtc::RTPFragmentationHeader>();
    header.m_value = header.m_ownedHeader.get();

    header.m_value->VerifyAndAllocateFragmentationHeader(size);
    for (size_t i = 0; i < header.m_value->Size(); ++i) {
        unsigned offset, length;
        if (!decoder.decode(offset))
            return false;
        if (!decoder.decode(length))
            return false;

        header.m_value->fragmentationOffset[i] = offset;
        header.m_value->fragmentationLength[i] = length;
    }

    return true;
}

}
