/*
 * Copyright (C) 2011 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "WebKitTestServer.h"

#include "TestMain.h"
#include <wtf/Threading.h>
#include <wtf/glib/GUniquePtr.h>
#include <wtf/threads/BinarySemaphore.h>

WebKitTestServer::WebKitTestServer(ServerOptionsBitSet options)
{
    if (options[ServerRunInThread]) {
        WTF::initialize();
        m_queue = WorkQueue::create("WebKitTestServer");
    }

    GRefPtr<GTlsCertificate> certificate;
    if (options[ServerHTTPS]) {
        GUniqueOutPtr<GError> error;
        CString resourcesDir = Test::getResourcesDir();
        GUniquePtr<char> sslCertificateFile(g_build_filename(resourcesDir.data(), "test-cert.pem", nullptr));
        GUniquePtr<char> sslKeyFile(g_build_filename(resourcesDir.data(), "test-key.pem", nullptr));
        certificate = adoptGRef(g_tls_certificate_new_from_files(sslCertificateFile.get(), sslKeyFile.get(), &error.outPtr()));
        g_assert_no_error(error.get());
    }

    m_soupServer = adoptGRef(soup_server_new("server-header", "WebKitTestServer ", "tls-certificate", certificate.get(), nullptr));
}

void WebKitTestServer::run(SoupServerCallback serverCallback)
{
    soup_server_add_handler(m_soupServer.get(), nullptr, serverCallback, nullptr, nullptr);

    unsigned options = SOUP_SERVER_LISTEN_IPV4_ONLY;
    if (soup_server_is_https(m_soupServer.get()))
        options |= SOUP_SERVER_LISTEN_HTTPS;

    if (m_queue) {
        m_queue->dispatchSync([&] {
            g_assert_true(soup_server_listen_local(m_soupServer.get(), 0, static_cast<SoupServerListenOptions>(options), nullptr));
        });
    } else
        g_assert_true(soup_server_listen_local(m_soupServer.get(), 0, static_cast<SoupServerListenOptions>(options), nullptr));

    GSList* uris = soup_server_get_uris(m_soupServer.get());
    g_assert_nonnull(uris);
#if USE(SOUP2)
    GUniquePtr<gchar> urlString(soup_uri_to_string(static_cast<SoupURI*>(uris->data), FALSE));
    m_baseURL = URL({ }, String::fromUTF8(urlString.get()));
    g_slist_free_full(uris, reinterpret_cast<GDestroyNotify>(soup_uri_free));
#else
    m_baseURL = static_cast<GUri*>(uris->data);
    g_slist_free_full(uris, reinterpret_cast<GDestroyNotify>(g_uri_unref));
#endif
}

void WebKitTestServer::addWebSocketHandler(SoupServerWebsocketCallback callback, gpointer userData)
{
    m_baseWebSocketURL = URL(m_baseURL, "/websocket/");
    m_baseWebSocketURL.setProtocol(m_baseWebSocketURL.protocolIs("http") ? "ws" : "wss");

    if (m_queue) {
        m_queue->dispatch([this, callback, userData] {
            soup_server_add_websocket_handler(m_soupServer.get(), "/websocket", nullptr, nullptr, callback, userData, nullptr);
        });
    } else
        soup_server_add_websocket_handler(m_soupServer.get(), "/websocket", nullptr, nullptr, callback, userData, nullptr);
}

void WebKitTestServer::removeWebSocketHandler()
{
    m_baseWebSocketURL = { };

    if (m_queue) {
        m_queue->dispatch([this] {
            soup_server_remove_handler(m_soupServer.get(), "/websocket");
        });
    } else
        soup_server_remove_handler(m_soupServer.get(), "/websocket");
}

CString WebKitTestServer::getWebSocketURIForPath(const char* path) const
{
    g_assert_false(m_baseWebSocketURL.isNull());
    g_assert_true(path && *path == '/');
    return URL(m_baseWebSocketURL, path + 1).string().utf8(); // Ignore the leading slash.
}

CString WebKitTestServer::getURIForPath(const char* path) const
{
    return URL(m_baseURL, path).string().utf8();
}

unsigned WebKitTestServer::port() const
{
    return m_baseURL.port().value_or(0);
}
