/*
 * 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.
 */

#include "config.h"
#include "RTCDtlsTransport.h"

#if ENABLE(WEB_RTC)

#include "Blob.h"
#include "EventNames.h"
#include "Logging.h"
#include "NotImplemented.h"
#include "RTCDtlsTransportBackend.h"
#include "RTCIceTransport.h"
#include "RTCPeerConnection.h"
#include "ScriptExecutionContext.h"
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(RTCDtlsTransport);

RTCDtlsTransport::RTCDtlsTransport(ScriptExecutionContext& context, UniqueRef<RTCDtlsTransportBackend>&& backend, Ref<RTCIceTransport>&& iceTransport)
    : ActiveDOMObject(&context)
    , m_backend(WTFMove(backend))
    , m_iceTransport(WTFMove(iceTransport))
{
    suspendIfNeeded();
    m_backend->registerClient(*this);
}

RTCDtlsTransport::~RTCDtlsTransport()
{
    m_backend->unregisterClient();
}

Vector<Ref<JSC::ArrayBuffer>> RTCDtlsTransport::getRemoteCertificates()
{
    return m_remoteCertificates;
}

void RTCDtlsTransport::stop()
{
    m_state = RTCDtlsTransportState::Closed;
}

bool RTCDtlsTransport::virtualHasPendingActivity() const
{
    return m_state != RTCDtlsTransportState::Closed && hasEventListeners();
}

void RTCDtlsTransport::onStateChanged(RTCDtlsTransportState state, Vector<Ref<JSC::ArrayBuffer>>&& certificates)
{
    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, state, certificates = WTFMove(certificates)]() mutable {
        if (m_state == RTCDtlsTransportState::Closed)
            return;

        if (m_remoteCertificates != certificates)
            m_remoteCertificates = WTFMove(certificates);

        if (m_state != state) {
            m_state = state;
            if (auto* connection = m_iceTransport->connection())
                connection->updateConnectionState();
            dispatchEvent(Event::create(eventNames().statechangeEvent, Event::CanBubble::Yes, Event::IsCancelable::No));
        }
    });
}

void RTCDtlsTransport::onError()
{
    onStateChanged(RTCDtlsTransportState::Failed, { });
}

} // namespace WebCore

#endif // ENABLE(WEB_RTC)
