/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * 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.
 */

#pragma once

#include "JSDOMMapLike.h"

namespace WebCore {

class RTCStatsReport : public RefCounted<RTCStatsReport> {
public:
    static Ref<RTCStatsReport> create() { return adoptRef(*new RTCStatsReport); }

    void synchronizeBackingMap(Ref<DOMMapLike>&& mapLike) { m_mapLike = WTFMove(mapLike); }
    DOMMapLike* backingMap() { return m_mapLike.get(); }

    template<typename Value> void addStats(typename Value::ParameterType&& value) { m_mapLike->set<IDLDOMString, Value>(value.id, std::forward<typename Value::ParameterType>(value)); }


    enum class Type {
        Codec,
        InboundRtp,
        OutboundRtp,
        PeerConnection,
        DataChannel,
        Track,
        Transport,
        CandidatePair,
        LocalCandidate,
        RemoteCandidate,
        Certificate
    };
    struct Stats {
        double timestamp;
        Type type;
        String id;
    };

    struct RTCRTPStreamStats : Stats {
        uint32_t ssrc;
        String associateStatsId;
        bool isRemote { false };
        String mediaType;

        String mediaTrackId;
        String transportId;
        String codecId;
        unsigned long firCount { 0 };
        unsigned long pliCount { 0 };
        unsigned long nackCount { 0 };
        unsigned long sliCount { 0 };
        unsigned long long qpSum { 0 };
    };

    struct InboundRTPStreamStats : RTCRTPStreamStats {
        InboundRTPStreamStats() { type = RTCStatsReport::Type::InboundRtp; }

        uint32_t ssrc;
        String associateStatsId;
        bool isRemote { false };
        String mediaType;
        String mediaTrackId;
        String transportId;
        String codecId;
        unsigned long firCount { 0 };
        unsigned long pliCount { 0 };
        unsigned long nackCount { 0 };
        unsigned long sliCount { 0 };
        unsigned long long qpSum { 0 };
        unsigned long packetsReceived { 0 };
        unsigned long long bytesReceived { 0 };
        unsigned long packetsLost { 0 };
        double jitter { 0 };
        double fractionLost { 0 };
        unsigned long packetsDiscarded { 0 };
        unsigned long packetsRepaired { 0 };
        unsigned long burstPacketsLost { 0 };
        unsigned long burstPacketsDiscarded { 0 };
        unsigned long burstLossCount { 0 };
        unsigned long burstDiscardCount { 0 };
        double burstLossRate { 0 };
        double burstDiscardRate { 0 };
        double gapLossRate { 0 };
        double gapDiscardRate { 0 };
        unsigned long framesDecoded { 0 };
    };

    struct OutboundRTPStreamStats : RTCRTPStreamStats {
        OutboundRTPStreamStats() { type = RTCStatsReport::Type::OutboundRtp; }

        unsigned long packetsSent { 0 };
        unsigned long long bytesSent { 0 };
        double targetBitrate { 0 };
        unsigned long framesEncoded { 0 };
    };

    struct MediaStreamTrackStats : Stats {
        MediaStreamTrackStats() { type = RTCStatsReport::Type::Track; }

        String trackIdentifier;
        bool remoteSource { false };
        bool ended { false };
        bool detached { false };
        unsigned long frameWidth { 0 };
        unsigned long frameHeight { 0 };
        double framesPerSecond { 0 };
        unsigned long framesSent { 0 };
        unsigned long framesReceived { 0 };
        unsigned long framesDecoded { 0 };
        unsigned long framesDropped { 0 };
        unsigned long framesCorrupted { 0 };
        unsigned long partialFramesLost { 0 };
        unsigned long fullFramesLost { 0 };
        double audioLevel { 0 };
        double echoReturnLoss { 0 };
        double echoReturnLossEnhancement { 0 };
    };

    struct DataChannelStats : Stats {
        DataChannelStats() { type = RTCStatsReport::Type::DataChannel; }
        
        String label;
        String protocol;
        long datachannelid { 0 };
        String state;
        unsigned long messagesSent { 0 };
        unsigned long long bytesSent { 0 };
        unsigned long messagesReceived { 0 };
        unsigned long long bytesReceived { 0 };
    };

    enum class IceCandidatePairState {
        Frozen,
        Waiting,
        Inprogress,
        Failed,
        Succeeded,
        Cancelled
    };

    struct IceCandidatePairStats : Stats {
        IceCandidatePairStats() { type = RTCStatsReport::Type::CandidatePair; }

        String transportId;
        String localCandidateId;
        String remoteCandidateId;
        IceCandidatePairState state;
        unsigned long long priority { 0 };
        bool nominated { false };
        bool writable { false };
        bool readable { false };
        unsigned long long bytesSent { 0 };
        unsigned long long bytesReceived { 0 };
        double totalRoundTripTime { 0 };
        double currentRoundTripTime { 0 };
        double availableOutgoingBitrate { 0 };
        double availableIncomingBitrate { 0 };
        unsigned long long requestsReceived { 0 };
        unsigned long long requestsSent { 0 };
        unsigned long long responsesReceived { 0 };
        unsigned long long responsesSent { 0 };
        unsigned long long retransmissionsReceived { 0 };
        unsigned long long retransmissionsSent { 0 };
        unsigned long long consentRequestsReceived { 0 };
        unsigned long long consentRequestsSent { 0 };
        unsigned long long consentResponsesReceived { 0 };
        unsigned long long consentResponsesSent { 0 };
    };

    struct CertificateStats : Stats {
        CertificateStats() { type = RTCStatsReport::Type::Certificate; }

        String fingerprint;
        String fingerprintAlgorithm;
        String base64Certificate;
        String issuerCertificateId;
    };

private:
    RTCStatsReport() = default;

private:
    RefPtr<DOMMapLike> m_mapLike;
};

} // namespace WebCore
