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

#include "config.h"
#include "RTCPacketOptions.h"

#if USE(LIBWEBRTC)

#include "DataReference.h"
#include "WebCoreArgumentCoders.h"
#include <WebCore/LibWebRTCEnumTraits.h>

namespace WebKit {

void RTCPacketOptions::encode(IPC::Encoder& encoder) const
{
    encoder << options.dscp;
    encoder << safeCast<int32_t>(options.packet_id);
    encoder << options.packet_time_params.rtp_sendtime_extension_id;

    encoder << static_cast<int64_t>(options.packet_time_params.srtp_auth_tag_len);
    if (options.packet_time_params.srtp_auth_tag_len > 0)
        encoder << IPC::DataReference(reinterpret_cast<const uint8_t*>(options.packet_time_params.srtp_auth_key.data()), options.packet_time_params.srtp_auth_key.size());

    encoder << options.packet_time_params.srtp_packet_index;
}

std::optional<RTCPacketOptions> RTCPacketOptions::decode(IPC::Decoder& decoder)
{
    rtc::PacketTimeUpdateParams params;
    rtc::PacketOptions options;

    rtc::DiffServCodePoint dscp;
    if (!decoder.decode(dscp))
        return std::nullopt;
    options.dscp = dscp;

    std::optional<int32_t> packetId;
    decoder >> packetId;
    if (!packetId)
        return std::nullopt;
    options.packet_id = packetId.value();

    std::optional<int> rtpSendtimeExtensionId;
    decoder >> rtpSendtimeExtensionId;
    if (!rtpSendtimeExtensionId)
        return std::nullopt;
    params.rtp_sendtime_extension_id = rtpSendtimeExtensionId.value();

    std::optional<int64_t> srtpAuthTagLength;
    decoder >> srtpAuthTagLength;
    if (!srtpAuthTagLength)
        return std::nullopt;
    params.srtp_auth_tag_len = srtpAuthTagLength.value();

    if (params.srtp_auth_tag_len > 0) {
        IPC::DataReference srtpAuthKey;
        if (!decoder.decode(srtpAuthKey))
            return std::nullopt;

        params.srtp_auth_key = std::vector<char>(static_cast<size_t>(srtpAuthKey.size()));
        memcpy(params.srtp_auth_key.data(), reinterpret_cast<const char*>(srtpAuthKey.data()), srtpAuthKey.size() * sizeof(char));
    }

    std::optional<int64_t> srtpPacketIndex;
    decoder >> srtpPacketIndex;
    if (!srtpPacketIndex)
        return std::nullopt;
    params.srtp_packet_index = srtpPacketIndex.value();

    options.packet_time_params = WTFMove(params);
    return RTCPacketOptions { WTFMove(options) };
}

}

#endif // USE(LIBWEBRTC)
