/*
 * Copyright (C) 2019 Sony Interactive Entertainment Inc.
 *
 * 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 "RemoteInspectorClient.h"

#if ENABLE(REMOTE_INSPECTOR)

#include "RemoteWebInspectorProxy.h"
#include <wtf/MainThread.h>
#include <wtf/text/Base64.h>

namespace WebKit {

class RemoteInspectorProxy final : public RemoteWebInspectorProxyClient {
    WTF_MAKE_FAST_ALLOCATED();
public:
    RemoteInspectorProxy(RemoteInspectorClient& inspectorClient, ConnectionID connectionID, TargetID targetID, const String& type)
        : m_proxy(RemoteWebInspectorProxy::create())
        , m_inspectorClient(inspectorClient)
        , m_connectionID(connectionID)
        , m_targetID(targetID)
        , m_debuggableType(type)
    {
        m_proxy->setClient(this);
    }

    ~RemoteInspectorProxy()
    {
        m_proxy->setClient(nullptr);
        m_proxy->invalidate();
    }

    void load()
    {
        m_proxy->load(m_debuggableType, m_inspectorClient.backendCommandsURL());
    }

    void show()
    {
        m_proxy->show();
    }

    void sendMessageToFrontend(const String& message)
    {
        m_proxy->sendMessageToFrontend(message);
    }

    void sendMessageToBackend(const String& message) override
    {
        m_inspectorClient.sendMessageToBackend(m_connectionID, m_targetID, message);
    }

    void closeFromFrontend() override
    {
        m_inspectorClient.closeFromFrontend(m_connectionID, m_targetID);
    }

private:
    Ref<RemoteWebInspectorProxy> m_proxy;
    RemoteInspectorClient& m_inspectorClient;
    ConnectionID m_connectionID;
    TargetID m_targetID;
    String m_debuggableType;
};

RemoteInspectorClient::RemoteInspectorClient(URL url, RemoteInspectorObserver& observer)
    : m_observer(observer)
{
    if (!url.host() || !url.port()) {
        LOG_ERROR("Invalid inspector url: %s", url.string().utf8().data());
        return;
    }

    m_connectionID = connectInet(url.host().utf8().data(), url.port().value());
    if (!m_connectionID) {
        LOG_ERROR("Inspector client could not connect to %s", url.string().utf8().data());
        return;
    }

    startInitialCommunication();
}

RemoteInspectorClient::~RemoteInspectorClient()
{
}

void RemoteInspectorClient::sendWebInspectorEvent(const String& event)
{
    ASSERT(isMainThread());
    ASSERT(m_connectionID.hasValue());
    auto message = event.utf8();
    send(m_connectionID.value(), reinterpret_cast<const uint8_t*>(message.data()), message.length());
}

HashMap<String, Inspector::RemoteInspectorConnectionClient::CallHandler>& RemoteInspectorClient::dispatchMap()
{
    static NeverDestroyed<HashMap<String, CallHandler>> dispatchMap = HashMap<String, CallHandler>({
        { "BackendCommands"_s, static_cast<CallHandler>(&RemoteInspectorClient::setBackendCommands) },
        { "SetTargetList"_s, static_cast<CallHandler>(&RemoteInspectorClient::setTargetList) },
        { "SendMessageToFrontend"_s, static_cast<CallHandler>(&RemoteInspectorClient::sendMessageToFrontend) },
    });

    return dispatchMap;
}

void RemoteInspectorClient::startInitialCommunication()
{
    auto event = JSON::Object::create();
    event->setString("event"_s, "SetupInspectorClient"_s);
    sendWebInspectorEvent(event->toJSONString());
}

void RemoteInspectorClient::connectionClosed()
{
    m_targets.clear();
    m_inspectorProxyMap.clear();
    m_observer.connectionClosed(*this);
    m_observer.targetListChanged(*this);
}

void RemoteInspectorClient::didClose(ConnectionID)
{
    callOnMainThread([this] {
        connectionClosed();
    });
}

void RemoteInspectorClient::inspect(ConnectionID connectionID, TargetID targetID, const String& type)
{
    auto addResult = m_inspectorProxyMap.ensure(std::make_pair(connectionID, targetID), [this, connectionID, targetID, &type] {
        return makeUnique<RemoteInspectorProxy>(*this, connectionID, targetID, type);
    });

    if (!addResult.isNewEntry) {
        addResult.iterator->value->show();
        return;
    }

    auto setupEvent = JSON::Object::create();
    setupEvent->setString("event"_s, "Setup"_s);
    setupEvent->setInteger("connectionID"_s, connectionID);
    setupEvent->setInteger("targetID"_s, targetID);
    sendWebInspectorEvent(setupEvent->toJSONString());

    addResult.iterator->value->load();
}

void RemoteInspectorClient::sendMessageToBackend(ConnectionID connectionID, TargetID targetID, const String& message)
{
    auto backendEvent = JSON::Object::create();
    backendEvent->setString("event"_s, "SendMessageToBackend"_s);
    backendEvent->setInteger("connectionID"_s, connectionID);
    backendEvent->setInteger("targetID"_s, targetID);
    backendEvent->setString("message"_s, message);
    sendWebInspectorEvent(backendEvent->toJSONString());
}

void RemoteInspectorClient::closeFromFrontend(ConnectionID connectionID, TargetID targetID)
{
    auto closedEvent = JSON::Object::create();
    closedEvent->setString("event"_s, "FrontendDidClose"_s);
    closedEvent->setInteger("connectionID"_s, connectionID);
    closedEvent->setInteger("targetID"_s, targetID);
    sendWebInspectorEvent(closedEvent->toJSONString());

    m_inspectorProxyMap.remove(std::make_pair(connectionID, targetID));
}

void RemoteInspectorClient::setBackendCommands(const Event& event)
{
    if (!event.message || event.message->isEmpty())
        return;

    m_backendCommandsURL = makeString("data:text/javascript;base64,", base64Encode(event.message->utf8()));
}

void RemoteInspectorClient::setTargetList(const Event& event)
{
    if (!event.connectionID || !event.message)
        return;

    RefPtr<JSON::Value> messageValue;
    if (!JSON::Value::parseJSON(event.message.value(), messageValue))
        return;

    RefPtr<JSON::Array> messageArray;
    if (!messageValue->asArray(messageArray))
        return;

    Vector<Target> targetList;
    for (auto& itemValue : *messageArray) {
        RefPtr<JSON::Object> itemObject;
        if (!itemValue->asObject(itemObject))
            continue;

        Target target;
        if (!itemObject->getInteger("targetID"_s, target.id)
            || !itemObject->getString("name"_s, target.name)
            || !itemObject->getString("url"_s, target.url)
            || !itemObject->getString("type"_s, target.type))
            continue;

        targetList.append(WTFMove(target));
    }

    auto connectionID = event.connectionID.value();

    // Find closed targets to remove them.
    Vector<TargetID, 4> targetsToRemove;
    for (auto& pair : m_inspectorProxyMap.keys()) {
        if (pair.first != connectionID)
            continue;

        bool found = false;
        for (auto& target : targetList) {
            if (target.id == pair.second) {
                found = true;
                break;
            }
        }

        if (!found)
            targetsToRemove.append(pair.second);
    }
    for (auto& targetID : targetsToRemove)
        m_inspectorProxyMap.remove(std::make_pair(connectionID, targetID));

    m_targets.set(connectionID, WTFMove(targetList));
    m_observer.targetListChanged(*this);
}

void RemoteInspectorClient::sendMessageToFrontend(const Event& event)
{
    if (!event.connectionID || !event.targetID || !event.message)
        return;

    auto proxy = m_inspectorProxyMap.get(std::make_pair(event.connectionID.value(), event.targetID.value()));
    if (!proxy) {
        ASSERT_NOT_REACHED();
        return;
    }

    proxy->sendMessageToFrontend(event.message.value());
}

} // namespace WebKit

#endif // ENABLE(REMOTE_INSPECTOR)
