/*
 * Copyright (C) 2017 Igalia S.L.
 *
 * 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 "SessionHost.h"

#include "WebDriverService.h"
#include <gio/gio.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/RunLoop.h>
#include <wtf/UUID.h>
#include <wtf/glib/GUniquePtr.h>

namespace WebDriver {

SessionHost::~SessionHost()
{
    g_cancellable_cancel(m_cancellable.get());
    if (m_socketConnection)
        m_socketConnection->close();
    if (m_browser)
        g_subprocess_force_exit(m_browser.get());
}

const SocketConnection::MessageHandlers& SessionHost::messageHandlers()
{
    static NeverDestroyed<const SocketConnection::MessageHandlers> messageHandlers = SocketConnection::MessageHandlers({
    { "DidClose", std::pair<CString, SocketConnection::MessageCallback> { { },
        [](SocketConnection&, GVariant*, gpointer userData) {
            auto& sessionHost = *static_cast<SessionHost*>(userData);
            sessionHost.connectionDidClose();
        }}
    },
    { "DidStartAutomationSession", std::pair<CString, SocketConnection::MessageCallback> { "(ss)",
        [](SocketConnection&, GVariant* parameters, gpointer userData) {
            auto& sessionHost = *static_cast<SessionHost*>(userData);
            sessionHost.didStartAutomationSession(parameters);
        }}
    },
    { "SetTargetList", std::pair<CString, SocketConnection::MessageCallback> { "(ta(tsssb))",
        [](SocketConnection&, GVariant* parameters, gpointer userData) {
            auto& sessionHost = *static_cast<SessionHost*>(userData);
            guint64 connectionID;
            GUniqueOutPtr<GVariantIter> iter;
            g_variant_get(parameters, "(ta(tsssb))", &connectionID, &iter.outPtr());
            size_t targetCount = g_variant_iter_n_children(iter.get());
            Vector<SessionHost::Target> targetList;
            targetList.reserveInitialCapacity(targetCount);
            guint64 targetID;
            const char* type;
            const char* name;
            const char* dummy;
            gboolean isPaired;
            while (g_variant_iter_loop(iter.get(), "(t&s&s&sb)", &targetID, &type, &name, &dummy, &isPaired)) {
                if (!g_strcmp0(type, "Automation"))
                    targetList.append({ targetID, name, static_cast<bool>(isPaired) });
            }
            sessionHost.setTargetList(connectionID, WTFMove(targetList));
        }}
    },
    { "SendMessageToFrontend", std::pair<CString, SocketConnection::MessageCallback> { "(tts)",
        [](SocketConnection&, GVariant* parameters, gpointer userData) {
            auto& sessionHost = *static_cast<SessionHost*>(userData);
            guint64 connectionID, targetID;
            const char* message;
            g_variant_get(parameters, "(tt&s)", &connectionID, &targetID, &message);
            sessionHost.sendMessageToFrontend(connectionID, targetID, message);
        }}
    }
    });
    return messageHandlers;
}

void SessionHost::connectToBrowser(Function<void (std::optional<String> error)>&& completionHandler)
{
    launchBrowser(WTFMove(completionHandler));
}

bool SessionHost::isConnected() const
{
    // Session is connected when launching or when socket connection hasn't been closed.
    return (m_browser || m_isRemoteBrowser) && (!m_socketConnection || !m_socketConnection->isClosed());
}

struct ConnectToBrowserAsyncData {
    WTF_DEPRECATED_MAKE_STRUCT_FAST_ALLOCATED(ConnectToBrowserAsyncData);
    ConnectToBrowserAsyncData(SessionHost* sessionHost, GUniquePtr<char>&& inspectorAddress, GCancellable* cancellable, Function<void(std::optional<String>)>&& completionHandler)
        : sessionHost(sessionHost)
        , inspectorAddress(WTFMove(inspectorAddress))
        , cancellable(cancellable)
        , completionHandler(WTFMove(completionHandler))
    {
    }

    SessionHost* sessionHost;
    GUniquePtr<char> inspectorAddress;
    GRefPtr<GCancellable> cancellable;
    Function<void (std::optional<String> error)> completionHandler;
};

static guint16 freePort()
{
    GRefPtr<GSocket> socket = adoptGRef(g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, nullptr));
    GRefPtr<GInetAddress> loopbackAdress = adoptGRef(g_inet_address_new_loopback(G_SOCKET_FAMILY_IPV4));
    GRefPtr<GSocketAddress> address = adoptGRef(g_inet_socket_address_new(loopbackAdress.get(), 0));
    g_socket_bind(socket.get(), address.get(), FALSE, nullptr);
    g_socket_listen(socket.get(), nullptr);
    address = adoptGRef(g_socket_get_local_address(socket.get(), nullptr));
    g_socket_close(socket.get(), nullptr);
    return g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(address.get()));
}

void SessionHost::launchBrowser(Function<void (std::optional<String> error)>&& completionHandler)
{
    String targetIp;
    uint16_t targetPort = 0;

    if (!m_targetIp.isEmpty() && m_targetPort) {
        targetIp = m_targetIp;
        targetPort = m_targetPort;
    } else if (m_capabilities.targetAddr && m_capabilities.targetPort) {
        targetIp = m_capabilities.targetAddr.value();
        targetPort = m_capabilities.targetPort.value();
    }

    m_cancellable = adoptGRef(g_cancellable_new());
    GUniquePtr<char> inspectorAddress(
        g_strdup_printf("%s:%u", targetIp.isEmpty() ? "127.0.0.1" : targetIp.latin1().data(), targetPort > 0 ? targetPort : freePort())
    );
    if (!targetIp.isEmpty()) {
        m_isRemoteBrowser = true;
        connectToBrowser(makeUnique<ConnectToBrowserAsyncData>(this, WTFMove(inspectorAddress), m_cancellable.get(), WTFMove(completionHandler)));
        return;
    }

    GRefPtr<GSubprocessLauncher> launcher = adoptGRef(g_subprocess_launcher_new(G_SUBPROCESS_FLAGS_NONE));
    g_subprocess_launcher_setenv(launcher.get(), "WEBKIT_INSPECTOR_SERVER", inspectorAddress.get(), TRUE);
#if PLATFORM(GTK)
    g_subprocess_launcher_setenv(launcher.get(), "GTK_OVERLAY_SCROLLING", m_capabilities.useOverlayScrollbars.value() ? "1" : "0", TRUE);
#endif

    size_t browserArgumentsSize = m_capabilities.browserArguments ? m_capabilities.browserArguments->size() : 0;
    GUniquePtr<char*> args(g_new0(char*, browserArgumentsSize + 2));
    args.get()[0] = g_strdup(m_capabilities.browserBinary.value().utf8().data());
    for (unsigned i = 0; i < browserArgumentsSize; ++i)
        args.get()[i + 1] = g_strdup(m_capabilities.browserArguments.value()[i].utf8().data());

    GUniqueOutPtr<GError> error;
    m_browser = adoptGRef(g_subprocess_launcher_spawnv(launcher.get(), args.get(), &error.outPtr()));
    if (error) {
        completionHandler(String::fromUTF8(error->message));
        return;
    }

    g_subprocess_wait_async(m_browser.get(), m_cancellable.get(), [](GObject* browser, GAsyncResult* result, gpointer userData) {
        GUniqueOutPtr<GError> error;
        g_subprocess_wait_finish(G_SUBPROCESS(browser), result, &error.outPtr());
        if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
            return;
        auto* sessionHost = static_cast<SessionHost*>(userData);
        sessionHost->m_browser = nullptr;
    }, this);

    connectToBrowser(makeUnique<ConnectToBrowserAsyncData>(this, WTFMove(inspectorAddress), m_cancellable.get(), WTFMove(completionHandler)));
}

void SessionHost::connectToBrowser(std::unique_ptr<ConnectToBrowserAsyncData>&& data)
{
    if (!m_browser && !m_isRemoteBrowser)
        return;

    RunLoop::mainSingleton().dispatchAfter(100_ms, [connectToBrowserData = WTFMove(data)]() mutable {
        auto* data = connectToBrowserData.release();
        if (g_cancellable_is_cancelled(data->cancellable.get()))
            return;

        GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new());
        g_socket_client_connect_to_host_async(socketClient.get(), data->inspectorAddress.get(), 0, data->cancellable.get(),
            [](GObject* client, GAsyncResult* result, gpointer userData) {
                auto data = std::unique_ptr<ConnectToBrowserAsyncData>(static_cast<ConnectToBrowserAsyncData*>(userData));
                GUniqueOutPtr<GError> error;
                GRefPtr<GSocketConnection> connection = adoptGRef(g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(client), result, &error.outPtr()));
                if (!connection) {
                    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
                        return;

                    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED)) {
                        data->sessionHost->connectToBrowser(WTFMove(data));
                        return;
                    }
                    data->completionHandler(String::fromUTF8(error->message));
                    return;
                }

                data->sessionHost->setupConnection(SocketConnection::create(WTFMove(connection), messageHandlers(), data->sessionHost));
                data->completionHandler(std::nullopt);
        }, data);
    });
}

void SessionHost::connectionDidClose()
{
    Ref<SessionHost> protectedThis(*this);
    m_browser = nullptr;
    m_isRemoteBrowser = false;

    inspectorDisconnected();
    m_socketConnection = nullptr;
    m_connectionID = 0;
    m_target = Target();
}

void SessionHost::setupConnection(Ref<SocketConnection>&& connection)
{
    ASSERT(!m_socketConnection);
    m_socketConnection = WTFMove(connection);
}

static bool matchBrowserOptions(const String& browserName, const String& browserVersion, const Capabilities& capabilities)
{
    if (capabilities.browserName && capabilities.browserName.value() != browserName)
        return false;

    if (capabilities.browserVersion && !WebDriverService::platformCompareBrowserVersions(capabilities.browserVersion.value(), browserVersion))
        return false;

    return true;
}

bool SessionHost::matchCapabilities(GVariant* capabilities)
{
    const char* name;
    const char* version;
    g_variant_get(capabilities, "(&s&s)", &name, &version);

    auto browserName = String::fromUTF8(name);
    auto browserVersion = String::fromUTF8(version);
    bool didMatch = matchBrowserOptions(browserName, browserVersion, m_capabilities);
    m_capabilities.browserName = browserName;
    m_capabilities.browserVersion = browserVersion;

    return didMatch;
}

bool SessionHost::buildSessionCapabilities(GVariantBuilder* builder) const
{
    if (!m_capabilities.acceptInsecureCerts && !m_capabilities.certificates && !m_capabilities.proxy)
        return false;

    g_variant_builder_init(builder, G_VARIANT_TYPE("a{sv}"));
    if (m_capabilities.acceptInsecureCerts)
        g_variant_builder_add(builder, "{sv}", "acceptInsecureCerts", g_variant_new_boolean(m_capabilities.acceptInsecureCerts.value()));

    if (m_capabilities.certificates) {
        GVariantBuilder arrayBuilder;
        g_variant_builder_init(&arrayBuilder, G_VARIANT_TYPE("a(ss)"));
        for (auto& certificate : *m_capabilities.certificates) {
            g_variant_builder_add_value(&arrayBuilder, g_variant_new("(ss)",
                certificate.first.utf8().data(), certificate.second.utf8().data()));
        }
        g_variant_builder_add(builder, "{sv}", "certificates", g_variant_builder_end(&arrayBuilder));
    }

    if (m_capabilities.proxy) {
        GVariantBuilder dictBuilder;
        g_variant_builder_init(&dictBuilder, G_VARIANT_TYPE("a{sv}"));
        g_variant_builder_add(&dictBuilder, "{sv}", "type", g_variant_new_string(m_capabilities.proxy->type.utf8().data()));
        if (m_capabilities.proxy->autoconfigURL)
            g_variant_builder_add(&dictBuilder, "{sv}", "autoconfigURL", g_variant_new_string(m_capabilities.proxy->autoconfigURL->string().utf8().data()));
        if (m_capabilities.proxy->ftpURL)
            g_variant_builder_add(&dictBuilder, "{sv}", "ftpURL", g_variant_new_string(m_capabilities.proxy->ftpURL->string().utf8().data()));
        if (m_capabilities.proxy->httpURL)
            g_variant_builder_add(&dictBuilder, "{sv}", "httpURL", g_variant_new_string(m_capabilities.proxy->httpURL->string().utf8().data()));
        if (m_capabilities.proxy->httpsURL)
            g_variant_builder_add(&dictBuilder, "{sv}", "httpsURL", g_variant_new_string(m_capabilities.proxy->httpsURL->string().utf8().data()));
        if (m_capabilities.proxy->socksURL) {
            URL socksURL = m_capabilities.proxy->socksURL.value();
            ASSERT(m_capabilities.proxy->socksVersion);
            switch (m_capabilities.proxy->socksVersion.value()) {
            case 4:
                if (URL::hostIsIPAddress(socksURL.host()))
                    socksURL.setProtocol("socks4"_s);
                else
                    socksURL.setProtocol("socks4a"_s);
                break;
            case 5:
                socksURL.setProtocol("socks5"_s);
                break;
            default:
                break;
            }
            g_variant_builder_add(&dictBuilder, "{sv}", "socksURL", g_variant_new_string(socksURL.string().utf8().data()));
        }
        if (!m_capabilities.proxy->ignoreAddressList.isEmpty()) {
            GUniquePtr<char*> ignoreAddressList(static_cast<char**>(g_new0(char*, m_capabilities.proxy->ignoreAddressList.size() + 1)));
            unsigned i = 0;
            for (const auto& ignoreAddress : m_capabilities.proxy->ignoreAddressList)
                ignoreAddressList.get()[i++] = g_strdup(ignoreAddress.utf8().data());
            g_variant_builder_add(&dictBuilder, "{sv}", "ignoreAddressList", g_variant_new_strv(ignoreAddressList.get(), -1));
        }
        g_variant_builder_add(builder, "{sv}", "proxy", g_variant_builder_end(&dictBuilder));
    }

    return true;
}

void SessionHost::startAutomationSession(Function<void (bool, std::optional<String>)>&& completionHandler)
{
    ASSERT(m_socketConnection);
    ASSERT(!m_startSessionCompletionHandler);
    m_startSessionCompletionHandler = WTFMove(completionHandler);
    m_sessionID = createVersion4UUIDString();
    GVariantBuilder builder;
    m_socketConnection->sendMessage("StartAutomationSession", g_variant_new("(sa{sv})", m_sessionID.utf8().data(), buildSessionCapabilities(&builder) ? &builder : nullptr));
}

void SessionHost::didStartAutomationSession(GVariant* parameters)
{
    if (matchCapabilities(parameters))
        return;

    auto completionHandler = std::exchange(m_startSessionCompletionHandler, nullptr);
    completionHandler(false, std::nullopt);
}

void SessionHost::setTargetList(uint64_t connectionID, Vector<Target>&& targetList)
{
    if (m_connectionID && m_connectionID != connectionID)
        return;

    ASSERT(targetList.size() <= 1);
    if (targetList.isEmpty()) {
        // An empty *automation* targetList may occur if the server is exposing other types of targets,
        // such as WebPage (this can be ignored), or if the server has removed the Automation target
        // because the session has ended (in this case, we must reset our state).
        if (m_connectionID) {
            if (m_socketConnection)
                m_socketConnection->close();
            connectionDidClose();
        }
        return;
    }


    if (!m_startSessionCompletionHandler) {
        // Session creation was already handled and we ignore different sessions
        return;
    }

    m_target = targetList[0];
    m_connectionID = connectionID;
    m_socketConnection->sendMessage("Setup", g_variant_new("(tt)", m_connectionID, m_target.id));

    auto startSessionCompletionHandler = std::exchange(m_startSessionCompletionHandler, nullptr);
    startSessionCompletionHandler(true, std::nullopt);
}

void SessionHost::sendMessageToFrontend(uint64_t connectionID, uint64_t targetID, const char* message)
{
    if (connectionID != m_connectionID || targetID != m_target.id)
        return;
    dispatchMessage(String::fromUTF8(message));
}

void SessionHost::sendMessageToBackend(const String& message)
{
    ASSERT(m_socketConnection);
    ASSERT(m_connectionID);
    ASSERT(m_target.id);
    m_socketConnection->sendMessage("SendMessageToBackend", g_variant_new("(tts)", m_connectionID, m_target.id, message.utf8().data()));
}

} // namespace WebDriver
