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

#include "config.h"
#include "RTCConfiguration.h"

#if ENABLE(MEDIA_STREAM)

#include "ArrayValue.h"
#include "Dictionary.h"
#include "ExceptionCode.h"
#include "URL.h"

namespace WebCore {

static bool validateIceServerURL(const String& iceURL)
{
    URL url(URL(), iceURL);
    if (url.isEmpty() || !url.isValid() || !(url.protocolIs("turn") || url.protocolIs("stun")))
        return false;

    return true;
}

static RefPtr<RTCIceServer> parseIceServer(const Dictionary& iceServer, ExceptionCode& ec)
{
    String credential, username;
    iceServer.get("credential", credential);
    iceServer.get("username", username);

    // Spec says that "urls" can be either a string or a sequence, so we must check for both.
    Vector<String> urlsList;
    String urlString;
    iceServer.get("urls", urlString);
    // This is the only way to check if "urls" is a sequence or a string. If we try to convert
    // to a sequence and it fails (in case it is a string), an exception will be set and the
    // RTCPeerConnection will fail.
    // So we convert to a string always, which converts a sequence to a string in the format: "foo, bar, ..",
    // then checking for a comma in the string assures that a string was a sequence and then we convert
    // it to a sequence safely.
    if (urlString.isEmpty()) {
        ec = INVALID_ACCESS_ERR;
        return nullptr;
    }

    if (urlString.find(',') != notFound && iceServer.get("urls", urlsList) && urlsList.size()) {
        for (auto iter = urlsList.begin(); iter != urlsList.end(); ++iter) {
            if (!validateIceServerURL(*iter)) {
                ec = INVALID_ACCESS_ERR;
                return nullptr;
            }
        }
    } else {
        if (!validateIceServerURL(urlString)) {
            ec = INVALID_ACCESS_ERR;
            return nullptr;
        }

        urlsList.append(urlString);
    }

    return RTCIceServer::create(urlsList, credential, username);
}

RefPtr<RTCConfiguration> RTCConfiguration::create(const Dictionary& configuration, ExceptionCode& ec)
{
    if (configuration.isUndefinedOrNull())
        return nullptr;

    RefPtr<RTCConfiguration> rtcConfiguration = adoptRef(new RTCConfiguration());
    rtcConfiguration->initialize(configuration, ec);
    if (ec)
        return nullptr;

    return rtcConfiguration;
}

RTCConfiguration::RTCConfiguration()
    : m_iceTransportPolicy("all")
    , m_bundlePolicy("balanced")
{
}

void RTCConfiguration::initialize(const Dictionary& configuration, ExceptionCode& ec)
{
    ArrayValue iceServers;
    bool ok = configuration.get("iceServers", iceServers);
    if (!ok || iceServers.isUndefinedOrNull()) {
        ec = TYPE_MISMATCH_ERR;
        return;
    }

    size_t numberOfServers;
    ok = iceServers.length(numberOfServers);
    if (!ok || !numberOfServers) {
        ec = !ok ? TYPE_MISMATCH_ERR : INVALID_ACCESS_ERR;
        return;
    }

    for (size_t i = 0; i < numberOfServers; ++i) {
        Dictionary iceServerDict;
        ok = iceServers.get(i, iceServerDict);
        if (!ok) {
            ec = TYPE_MISMATCH_ERR;
            return;
        }

        RefPtr<RTCIceServer> iceServer = parseIceServer(iceServerDict, ec);
        if (!iceServer)
            return;

        m_iceServers.append(WTF::move(iceServer));
    }

    String iceTransportPolicy;
    if (configuration.get("iceTransportPolicy", iceTransportPolicy)) {
        if (iceTransportPolicy == "none" || iceTransportPolicy == "relay" || iceTransportPolicy == "all")
            m_iceTransportPolicy = iceTransportPolicy;
        else {
            ec = TypeError;
            return;
        }
    }

    String bundlePolicy;
    if (configuration.get("bundlePolicy", bundlePolicy)) {
        if (bundlePolicy == "balanced" || bundlePolicy == "max-compat" || bundlePolicy == "max-bundle")
            m_bundlePolicy = bundlePolicy;
        else
            ec = TypeError;
    }
}

} // namespace WebCore

#endif // ENABLE(MEDIA_STREAM)
