/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 * Copyright (C) 2011 Ericsson AB. 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 "PeerConnection.h"

#if ENABLE(MEDIA_STREAM)

#include "ExceptionCode.h"
#include "MediaStreamEvent.h"
#include "MessageEvent.h"
#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"

namespace WebCore {

PassRefPtr<PeerConnection> PeerConnection::create(ScriptExecutionContext* context, const String& serverConfiguration, PassRefPtr<SignalingCallback> signalingCallback)
{
    RefPtr<PeerConnection> connection = adoptRef(new PeerConnection(context, serverConfiguration, signalingCallback));
    connection->setPendingActivity(connection.get());
    connection->scheduleInitialNegotiation();
    connection->suspendIfNeeded();

    return connection.release();
}

PeerConnection::PeerConnection(ScriptExecutionContext* context, const String& serverConfiguration, PassRefPtr<SignalingCallback> signalingCallback)
    : ActiveDOMObject(context, this)
    , m_signalingCallback(signalingCallback)
    , m_readyState(NEW)
    , m_iceStarted(false)
    , m_localStreams(MediaStreamList::create())
    , m_remoteStreams(MediaStreamList::create())
    , m_initialNegotiationTimer(this, &PeerConnection::initialNegotiationTimerFired)
    , m_streamChangeTimer(this, &PeerConnection::streamChangeTimerFired)
    , m_readyStateChangeTimer(this, &PeerConnection::readyStateChangeTimerFired)
    , m_peerHandler(PeerConnectionHandler::create(this, serverConfiguration, context->securityOrigin()))
{
}

PeerConnection::~PeerConnection()
{
}

void PeerConnection::processSignalingMessage(const String& message, ExceptionCode& ec)
{
    if (m_readyState == CLOSED) {
        ec = INVALID_STATE_ERR;
        return;
    }

    if (!message.startsWith("SDP\n"))
        return;

    String sdp = message.substring(4);

    if (m_iceStarted) {
        if (m_peerHandler)
            m_peerHandler->processSDP(sdp);
        return;
    }

    if (m_peerHandler)
        m_peerHandler->handleInitialOffer(sdp);

    ensureStreamChangeScheduled();
    m_iceStarted = true;
    scheduleReadyStateChange(NEGOTIATING);
}

PeerConnection::ReadyState PeerConnection::readyState() const
{
    return m_readyState;
}

void PeerConnection::send(const String& text, ExceptionCode& ec)
{
    if (m_readyState == CLOSED) {
        ec = INVALID_STATE_ERR;
        return;
    }

    CString data = text.utf8();
    unsigned length = data.length();

    if (length > 504) {
        ec = INVALID_ACCESS_ERR;
        return;
    }

    if (m_peerHandler)
        m_peerHandler->sendDataStreamMessage(data.data(), length);
}

void PeerConnection::addStream(PassRefPtr<MediaStream> prpStream, ExceptionCode& ec)
{
    RefPtr<MediaStream> stream = prpStream;
    if (!stream) {
        ec =  TYPE_MISMATCH_ERR;
        return;
    }

    if (m_readyState == CLOSED) {
        ec = INVALID_STATE_ERR;
        return;
    }

    if (m_localStreams->contains(stream.get()))
        return;

    m_localStreams->append(stream);

    MediaStreamDescriptor* streamDescriptor = stream->descriptor();
    size_t i = m_pendingRemoveStreams.find(streamDescriptor);
    if (i != notFound) {
        m_pendingRemoveStreams.remove(i);
        return;
    }

    m_pendingAddStreams.append(streamDescriptor);
    if (m_iceStarted)
        ensureStreamChangeScheduled();
}

void PeerConnection::removeStream(MediaStream* stream, ExceptionCode& ec)
{
    if (m_readyState == CLOSED) {
        ec = INVALID_STATE_ERR;
        return;
    }

    if (!stream) {
        ec = TYPE_MISMATCH_ERR;
        return;
    }

    if (!m_localStreams->contains(stream))
        return;

    m_localStreams->remove(stream);

    MediaStreamDescriptor* streamDescriptor = stream->descriptor();
    size_t i = m_pendingAddStreams.find(streamDescriptor);
    if (i != notFound) {
        m_pendingAddStreams.remove(i);
        return;
    }

    m_pendingRemoveStreams.append(streamDescriptor);
    if (m_iceStarted)
        ensureStreamChangeScheduled();
}

MediaStreamList* PeerConnection::localStreams() const
{
    return m_localStreams.get();
}

MediaStreamList* PeerConnection::remoteStreams() const
{
    return m_remoteStreams.get();
}

void PeerConnection::close(ExceptionCode& ec)
{
    if (m_readyState == CLOSED) {
        ec = INVALID_STATE_ERR;
        return;
    }

    stop();
}

void PeerConnection::didCompleteICEProcessing()
{
    ASSERT(scriptExecutionContext()->isContextThread());
    changeReadyState(ACTIVE);
}

void PeerConnection::didGenerateSDP(const String& sdp)
{
    ASSERT(scriptExecutionContext()->isContextThread());
    m_signalingCallback->handleEvent("SDP\n" + sdp, this);
}

void PeerConnection::didReceiveDataStreamMessage(const char* data, size_t length)
{
    ASSERT(scriptExecutionContext()->isContextThread());
    const String& message = String::fromUTF8(data, length);
    dispatchEvent(MessageEvent::create(PassOwnPtr<MessagePortArray>(), SerializedScriptValue::create(message)));
}

void PeerConnection::didAddRemoteStream(PassRefPtr<MediaStreamDescriptor> streamDescriptor)
{
    ASSERT(scriptExecutionContext()->isContextThread());

    if (m_readyState == CLOSED)
        return;

    RefPtr<MediaStream> stream = MediaStream::create(scriptExecutionContext(), streamDescriptor);
    m_remoteStreams->append(stream);

    dispatchEvent(MediaStreamEvent::create(eventNames().addstreamEvent, false, false, stream.release()));
}

void PeerConnection::didRemoveRemoteStream(MediaStreamDescriptor* streamDescriptor)
{
    ASSERT(scriptExecutionContext()->isContextThread());
    ASSERT(streamDescriptor->owner());

    RefPtr<MediaStream> stream = static_cast<MediaStream*>(streamDescriptor->owner());
    stream->streamEnded();

    if (m_readyState == CLOSED)
        return;

    ASSERT(m_remoteStreams->contains(stream.get()));
    m_remoteStreams->remove(stream.get());

    dispatchEvent(MediaStreamEvent::create(eventNames().removestreamEvent, false, false, stream.release()));
}

const AtomicString& PeerConnection::interfaceName() const
{
    return eventNames().interfaceForPeerConnection;
}

ScriptExecutionContext* PeerConnection::scriptExecutionContext() const
{
    return ActiveDOMObject::scriptExecutionContext();
}

void PeerConnection::stop()
{
    if (m_readyState == CLOSED)
        return;

    m_initialNegotiationTimer.stop();
    m_streamChangeTimer.stop();
    m_readyStateChangeTimer.stop();

    if (m_peerHandler)
        m_peerHandler->stop();

    unsetPendingActivity(this);
    m_peerHandler.clear();

    changeReadyState(CLOSED);
}

EventTargetData* PeerConnection::eventTargetData()
{
    return &m_eventTargetData;
}

EventTargetData* PeerConnection::ensureEventTargetData()
{
    return &m_eventTargetData;
}

void PeerConnection::scheduleInitialNegotiation()
{
    ASSERT(!m_initialNegotiationTimer.isActive());

    m_initialNegotiationTimer.startOneShot(0);
}

void PeerConnection::initialNegotiationTimerFired(Timer<PeerConnection>* timer)
{
    ASSERT_UNUSED(timer, timer == &m_initialNegotiationTimer);

    if (m_iceStarted)
        return;

    MediaStreamDescriptorVector pendingAddStreams;
    m_pendingAddStreams.swap(pendingAddStreams);
    if (m_peerHandler)
        m_peerHandler->produceInitialOffer(pendingAddStreams);

    m_iceStarted = true;

    changeReadyState(NEGOTIATING);
}

void PeerConnection::ensureStreamChangeScheduled()
{
    if (!m_streamChangeTimer.isActive())
        m_streamChangeTimer.startOneShot(0);
}

void PeerConnection::streamChangeTimerFired(Timer<PeerConnection>* timer)
{
    ASSERT_UNUSED(timer, timer == &m_streamChangeTimer);

    if (!m_pendingAddStreams.isEmpty() && !m_pendingRemoveStreams.isEmpty())
        return;

    MediaStreamDescriptorVector pendingAddStreams;
    MediaStreamDescriptorVector pendingRemoveStreams;

    m_pendingAddStreams.swap(pendingAddStreams);
    m_pendingRemoveStreams.swap(pendingRemoveStreams);

    if (m_peerHandler)
        m_peerHandler->processPendingStreams(pendingAddStreams, pendingRemoveStreams);

    if (!pendingAddStreams.isEmpty())
        changeReadyState(NEGOTIATING);
}

void PeerConnection::scheduleReadyStateChange(ReadyState readyState)
{
    m_pendingReadyStates.append(readyState);
    if (!m_readyStateChangeTimer.isActive())
        m_readyStateChangeTimer.startOneShot(0);
}

void PeerConnection::readyStateChangeTimerFired(Timer<PeerConnection>* timer)
{
    ASSERT_UNUSED(timer, timer == &m_readyStateChangeTimer);

    Vector<ReadyState> pendingReadyStates;
    m_pendingReadyStates.swap(pendingReadyStates);

    for (size_t i = 0; i < pendingReadyStates.size(); i++)
        changeReadyState(pendingReadyStates[i]);
}

void PeerConnection::changeReadyState(ReadyState readyState)
{
    if (readyState == m_readyState)
        return;

    m_readyState = readyState;

    switch (m_readyState) {
    case NEW:
        ASSERT_NOT_REACHED();
        break;
    case NEGOTIATING:
        dispatchEvent(Event::create(eventNames().connectingEvent, false, false));
        break;
    case ACTIVE:
        dispatchEvent(Event::create(eventNames().openEvent, false, false));
        break;
    case CLOSED:
        break;
    }
}

} // namespace WebCore

#endif // ENABLE(MEDIA_STREAM)
