/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
 * Copyright (C) 2015 Ericsson AB. 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.
 * 3. Neither the name of Google Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER 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(WEB_RTC)

#include "ActiveDOMObject.h"
#include "EventTarget.h"
#include "MediaEndpointConfiguration.h"
#include "MediaStream.h"
#include "RTCConfiguration.h"
#include "RTCDataChannel.h"
#include "RTCIceConnectionState.h"
#include "RTCIceGatheringState.h"
#include "RTCPeerConnectionState.h"
#include "RTCRtpTransceiver.h"
#include "RTCSignalingState.h"
#include <JavaScriptCore/Uint8Array.h>
#include <wtf/LoggerHelper.h>

namespace WebCore {

class MediaStream;
class MediaStreamTrack;
class PeerConnectionBackend;
class RTCController;
class RTCIceCandidate;
class RTCPeerConnectionErrorCallback;
class RTCSessionDescription;
class RTCStatsCallback;

struct RTCAnswerOptions;
struct RTCOfferOptions;
struct RTCRtpParameters;

struct RTCRtpTransceiverInit {
    RTCRtpTransceiverDirection direction { RTCRtpTransceiverDirection::Sendrecv };
    Vector<RefPtr<MediaStream>> streams;
};

class RTCPeerConnection final
    : public RefCounted<RTCPeerConnection>
    , public EventTargetWithInlineData
    , public ActiveDOMObject
#if !RELEASE_LOG_DISABLED
    , private LoggerHelper
#endif
{
    WTF_MAKE_ISO_ALLOCATED(RTCPeerConnection);
public:
    static Ref<RTCPeerConnection> create(ScriptExecutionContext&);
    virtual ~RTCPeerConnection();

    using DataChannelInit = RTCDataChannelInit;

    ExceptionOr<void> initializeWith(Document&, RTCConfiguration&&);

    struct CertificateParameters {
        String name;
        String hash;
        String namedCurve;
        Optional<uint32_t> modulusLength;
        RefPtr<Uint8Array> publicExponent;
        Optional<double> expires;
    };

    using AlgorithmIdentifier = Variant<JSC::Strong<JSC::JSObject>, String>;
    static void generateCertificate(JSC::JSGlobalObject&, AlgorithmIdentifier&&, DOMPromiseDeferred<IDLInterface<RTCCertificate>>&&);

    // 4.3.2 RTCPeerConnection Interface
    void queuedCreateOffer(RTCOfferOptions&&, PeerConnection::SessionDescriptionPromise&&);
    void queuedCreateAnswer(RTCAnswerOptions&&, PeerConnection::SessionDescriptionPromise&&);

    void queuedSetLocalDescription(RTCSessionDescription&, DOMPromiseDeferred<void>&&);
    RefPtr<RTCSessionDescription> localDescription() const;
    RefPtr<RTCSessionDescription> currentLocalDescription() const;
    RefPtr<RTCSessionDescription> pendingLocalDescription() const;

    void queuedSetRemoteDescription(RTCSessionDescription&, DOMPromiseDeferred<void>&&);
    RefPtr<RTCSessionDescription> remoteDescription() const;
    RefPtr<RTCSessionDescription> currentRemoteDescription() const;
    RefPtr<RTCSessionDescription> pendingRemoteDescription() const;

    void queuedAddIceCandidate(RTCIceCandidate*, DOMPromiseDeferred<void>&&);

    RTCSignalingState signalingState() const { return m_signalingState; }
    RTCIceGatheringState iceGatheringState() const { return m_iceGatheringState; }
    RTCIceConnectionState iceConnectionState() const { return m_iceConnectionState; }
    RTCPeerConnectionState connectionState() const { return m_connectionState; }

    const RTCConfiguration& getConfiguration() const { return m_configuration; }
    ExceptionOr<void> setConfiguration(RTCConfiguration&&);
    void close();

    bool isClosed() const { return m_connectionState == RTCPeerConnectionState::Closed; }
    bool isStopped() const { return m_isStopped; }

    void addInternalTransceiver(Ref<RTCRtpTransceiver>&& transceiver) { m_transceiverSet->append(WTFMove(transceiver)); }

    // 5.1 RTCPeerConnection extensions
    Vector<std::reference_wrapper<RTCRtpSender>> getSenders() const;
    Vector<std::reference_wrapper<RTCRtpReceiver>> getReceivers() const;
    const Vector<RefPtr<RTCRtpTransceiver>>& getTransceivers() const;

    const Vector<RefPtr<RTCRtpTransceiver>>& currentTransceivers() const { return m_transceiverSet->list(); }

    ExceptionOr<Ref<RTCRtpSender>> addTrack(Ref<MediaStreamTrack>&&, const Vector<std::reference_wrapper<MediaStream>>&);
    ExceptionOr<void> removeTrack(RTCRtpSender&);

    using AddTransceiverTrackOrKind = Variant<RefPtr<MediaStreamTrack>, String>;
    ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(AddTransceiverTrackOrKind&&, const RTCRtpTransceiverInit&);

    // 6.1 Peer-to-peer data API
    ExceptionOr<Ref<RTCDataChannel>> createDataChannel(String&&, RTCDataChannelInit&&);

    // 8.2 Statistics API
    void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&);

    // EventTarget
    EventTargetInterface eventTargetInterface() const final { return RTCPeerConnectionEventTargetInterfaceType; }
    ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }

    using RefCounted::ref;
    using RefCounted::deref;

    // Used for testing with a mock
    WEBCORE_EXPORT void emulatePlatformEvent(const String& action);

    // API used by PeerConnectionBackend and relatives
    void addTransceiver(Ref<RTCRtpTransceiver>&&);
    void setSignalingState(RTCSignalingState);
    void updateIceGatheringState(RTCIceGatheringState);
    void updateIceConnectionState(RTCIceConnectionState);

    void scheduleNegotiationNeededEvent();

    void dispatchEventWhenFeasible(Ref<Event>&&);

    void disableICECandidateFiltering() { m_backend->disableICECandidateFiltering(); }
    void enableICECandidateFiltering() { m_backend->enableICECandidateFiltering(); }

    void clearController() { m_controller = nullptr; }

    // ActiveDOMObject.
    bool hasPendingActivity() const final;
    
    Document* document();

    void doTask(Function<void()>&&);

#if !RELEASE_LOG_DISABLED
    const Logger& logger() const final { return m_logger.get(); }
    const void* logIdentifier() const final { return m_logIdentifier; }
    const char* logClassName() const final { return "RTCPeerConnection"; }
    WTFLogChannel& logChannel() const final;
#endif

private:
    template<typename PromiseType> void addPendingPromise(PromiseType& promise)
    {
        promise.whenSettled([pendingActivity = makePendingActivity(*this)] { });
    }

    RTCPeerConnection(Document&);

    ExceptionOr<void> initializeConfiguration(RTCConfiguration&&);
    Ref<RTCRtpTransceiver> completeAddTransceiver(Ref<RTCRtpSender>&&, const RTCRtpTransceiverInit&, const String& trackId, const String& trackKind);

    void registerToController(RTCController&);
    void unregisterFromController();

    friend class Internals;
    void applyRotationForOutgoingVideoSources() { m_backend->applyRotationForOutgoingVideoSources(); }

    // EventTarget implementation.
    void refEventTarget() final { ref(); }
    void derefEventTarget() final { deref(); }
    void dispatchEvent(Event&) final;

    // ActiveDOMObject
    WEBCORE_EXPORT void stop() final;
    const char* activeDOMObjectName() const final;
    void suspend(ReasonForSuspension) final;
    void resume() final;

    void updateConnectionState();
    bool doClose();
    void doStop();

    ExceptionOr<Vector<MediaEndpointConfiguration::CertificatePEM>> certificatesFromConfiguration(const RTCConfiguration&);

    bool m_isStopped { false };
    RTCSignalingState m_signalingState { RTCSignalingState::Stable };
    RTCIceGatheringState m_iceGatheringState { RTCIceGatheringState::New };
    RTCIceConnectionState m_iceConnectionState { RTCIceConnectionState::New };
    RTCPeerConnectionState m_connectionState { RTCPeerConnectionState::New };

#if !RELEASE_LOG_DISABLED
    Ref<const Logger> m_logger;
    const void* m_logIdentifier;
#endif

    std::unique_ptr<RtpTransceiverSet> m_transceiverSet { std::unique_ptr<RtpTransceiverSet>(new RtpTransceiverSet()) };

    std::unique_ptr<PeerConnectionBackend> m_backend;

    RTCConfiguration m_configuration;
    RTCController* m_controller { nullptr };
    Vector<RefPtr<RTCCertificate>> m_certificates;
    bool m_shouldDelayTasks { false };
    Vector<Function<void()>> m_pendingTasks;
};

} // namespace WebCore

#endif // ENABLE(WEB_RTC)
