/*
 * Copyright (C) 2021 Igalia S.L.
 * Copyright (C) 2022 Apple Inc. All rights reserved.
 *
 * 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 "AccessibilityAtspi.h"

#if ENABLE(ACCESSIBILITY) && USE(ATSPI)
#include "AccessibilityAtspiInterfaces.h"
#include "AccessibilityRootAtspi.h"
#include <gio/gio.h>
#include <glib/gi18n-lib.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/SortedArrayMap.h>
#include <wtf/UUID.h>
#include <wtf/glib/RunLoopSourcePriority.h>

namespace WebCore {

AccessibilityAtspi& AccessibilityAtspi::singleton()
{
    static NeverDestroyed<AccessibilityAtspi> atspi;
    return atspi;
}

AccessibilityAtspi::AccessibilityAtspi()
    : m_cacheUpdateTimer(RunLoop::main(), this, &AccessibilityAtspi::cacheUpdateTimerFired)
    , m_cacheClearTimer(RunLoop::main(), this, &AccessibilityAtspi::cacheClearTimerFired)
{
    m_cacheUpdateTimer.setPriority(RunLoopSourcePriority::RunLoopDispatcher);
    m_cacheClearTimer.setPriority(RunLoopSourcePriority::ReleaseUnusedResourcesTimer);
}

void AccessibilityAtspi::connect(const String& busAddress)
{
    if (busAddress.isEmpty())
        return;

    m_isConnecting = true;
    g_dbus_connection_new_for_address(busAddress.utf8().data(),
        static_cast<GDBusConnectionFlags>(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), nullptr, nullptr,
        [](GObject*, GAsyncResult* result, gpointer userData) {
            auto& atspi = *static_cast<AccessibilityAtspi*>(userData);
            GUniqueOutPtr<GError> error;
            atspi.didConnect(adoptGRef(g_dbus_connection_new_for_address_finish(result, &error.outPtr())));
            if (error)
                g_warning("Can't connect to a11y bus: %s", error->message);
        }, this);
}

void AccessibilityAtspi::didConnect(GRefPtr<GDBusConnection>&& connection)
{
    m_isConnecting = false;
    m_connection = WTFMove(connection);
    if (!m_connection)
        return;

    for (auto& pendingRegistration : m_pendingRootRegistrations)
        registerRoot(pendingRegistration.root, WTFMove(pendingRegistration.interfaces), WTFMove(pendingRegistration.completionHandler));
    m_pendingRootRegistrations.clear();

    initializeRegistry();
}

void AccessibilityAtspi::initializeRegistry()
{
    RELEASE_ASSERT(m_connection);
    g_dbus_proxy_new(m_connection.get(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, nullptr,
        "org.a11y.atspi.Registry", "/org/a11y/atspi/registry", "org.a11y.atspi.Registry", nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
        auto& atspi = *static_cast<AccessibilityAtspi*>(userData);
        GUniqueOutPtr<GError> error;
        atspi.m_registry = adoptGRef(g_dbus_proxy_new_finish(result, &error.outPtr()));
        if (!atspi.m_registry) {
            g_warning("Failed to connect to atspi registry: %s\n", error->message);
            return;
        }

        g_signal_connect(atspi.m_registry.get(), "g-signal", G_CALLBACK(+[](GDBusProxy*, char*, char* signal, GVariant* parameters, AccessibilityAtspi* atspi) {
            const char* dbusName;
            const char* eventName;
            if (!g_strcmp0(signal, "EventListenerRegistered")) {
                g_variant_get(parameters, "(&s&s@as)", &dbusName, &eventName, nullptr);
                atspi->addEventListener(dbusName, eventName);
            } else if (!g_strcmp0(signal, "EventListenerDeregistered")) {
                g_variant_get(parameters, "(&s&s)", &dbusName, &eventName);
                atspi->removeEventListener(dbusName, eventName);
            }
        }), &atspi);

        g_dbus_proxy_call(atspi.m_registry.get(), "GetRegisteredEvents", nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, [](GObject* proxy, GAsyncResult* result, gpointer userData) {
            auto& atspi = *static_cast<AccessibilityAtspi*>(userData);
            GUniqueOutPtr<GError> error;
            GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), result, &error.outPtr()));
            if (!resultVariant) {
                g_warning("Failed to get atspi registered event listeners: %s\n", error->message);
                return;
            }

            GRefPtr<GVariant> events;
            g_variant_get(resultVariant.get(), "(@a(ss))", &events.outPtr());
            GVariantIter iter;
            g_variant_iter_init(&iter, events.get());
            const char* dbusName;
            const char* eventName;
            while (g_variant_iter_loop(&iter, "(&s&s)", &dbusName, &eventName))
                atspi.addEventListener(dbusName, eventName);
        }, &atspi);
    }, this);
}

static GUniquePtr<char*> eventConvertingDetailToNonCamelCase(const char* eventName)
{
    GUniquePtr<char*> event(g_strsplit(eventName, ":", 3));
    if (!event.get()[0] || !event.get()[1] || !event.get()[2] || !*event.get()[2])
        return event;

    char* converted = static_cast<char*>(g_malloc(strlen(event.get()[2]) * 2 + 1));
    char* convertedPtr = converted;
    char* detailPtr = event.get()[2];

    while (*detailPtr) {
        if (isASCIIUpper(*detailPtr)) {
            if (convertedPtr > converted)
                *convertedPtr++ = '-';
            *convertedPtr++ = toASCIILower(*detailPtr++);
        } else
            *convertedPtr++ = *detailPtr++;
    }
    *convertedPtr = '\0';

    g_free(event.get()[2]);
    event.get()[2] = converted;

    return event;
}

void AccessibilityAtspi::addEventListener(const char* dbusName, const char* eventName)
{
    auto& listeners = m_eventListeners.ensure(dbusName, [] {
        return Vector<GUniquePtr<char*>> { };
    }).iterator->value;
    listeners.append(eventConvertingDetailToNonCamelCase(eventName));
    addClient(dbusName);
}

static bool eventIsSubtype(char** needle, char** haystack)
{
    while (*haystack && **haystack) {
        if (g_strcmp0(*needle, *haystack))
            return false;
        needle++;
        haystack++;
    }

    return true;
}

void AccessibilityAtspi::removeEventListener(const char* dbusName, const char* eventName)
{
    if (!eventName || !*eventName) {
        m_eventListeners.remove(dbusName);
        return;
    }

    auto it = m_eventListeners.find(dbusName);
    if (it == m_eventListeners.end())
        return;

    auto needle = eventConvertingDetailToNonCamelCase(eventName);
    it->value.removeAllMatching([&](const GUniquePtr<char*>& event) {
        return eventIsSubtype(needle.get(), event.get());
    });

    if (it->value.isEmpty())
        m_eventListeners.remove(it);
}

void AccessibilityAtspi::addClient(const char* dbusName)
{
    if (m_clients.isEmpty())
        AXObjectCache::enableAccessibility();

    auto addResult = m_clients.add(dbusName, 0);
    if (!addResult.isNewEntry)
        return;

    m_cacheClearTimer.stop();

    addResult.iterator->value = g_dbus_connection_signal_subscribe(m_connection.get(), nullptr, "org.freedesktop.DBus", "NameOwnerChanged", nullptr, dbusName,
        G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, GVariant* parameters, gpointer userData) {
            auto& atspi = *static_cast<AccessibilityAtspi*>(userData);
            const char* interface;
            const char* oldName;
            const char* newName;
            g_variant_get(parameters, "(&s&s&s)", &interface, &oldName, &newName);
            if (*oldName != '\0' && *newName == '\0')
                atspi.removeClient(oldName);
        }, this, nullptr);
}

void AccessibilityAtspi::removeClient(const char* dbusName)
{
    auto id = m_clients.take(dbusName);
    if (!id)
        return;

    g_dbus_connection_signal_unsubscribe(m_connection.get(), id);

    if (!m_clients.isEmpty())
        return;

    m_cacheUpdateList.clear();
    m_cacheUpdateTimer.stop();
    m_cacheClearTimer.startOneShot(10_s);
}

bool AccessibilityAtspi::shouldEmitSignal(const char* interface, const char* name, const char* detail)
{
    // Always emit signals if we couldn't connect to the registry.
    if (!m_registry)
        return true;

    if (m_eventListeners.isEmpty())
        return false;

    const char* needle[4] = { interface, name, detail, nullptr };
    for (const auto& listeners : m_eventListeners.values()) {
        auto result = listeners.findIf([&](const GUniquePtr<char*>& event) {
            return eventIsSubtype(const_cast<char**>(needle), event.get());
        });
        if (result != notFound)
            return true;
    }

    return false;
}

const char* AccessibilityAtspi::uniqueName() const
{
    return m_connection ? g_dbus_connection_get_unique_name(m_connection.get()) : nullptr;
}

GVariant* AccessibilityAtspi::nullReference() const
{
    return g_variant_new("(so)", uniqueName(), "/org/a11y/atspi/null");
}

GVariant* AccessibilityAtspi::applicationReference() const
{
    // The application is the same for all root objects, so just use the first root object that is already embedded.
    for (auto* rootObject : m_rootObjects.keys()) {
        if (!rootObject->path().isNull())
            return rootObject->applicationReference();
    }

    return nullReference();
}

void AccessibilityAtspi::registerRoot(AccessibilityRootAtspi& rootObject, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&& interfaces, CompletionHandler<void(const String&)>&& completionHandler)
{
    if (m_isConnecting) {
        m_pendingRootRegistrations.append({ rootObject, WTFMove(interfaces), WTFMove(completionHandler) });
        return;
    }

    if (!m_connection) {
        completionHandler({ });
        return;
    }

    ensureCache();
    String path = makeString("/org/a11y/webkit/accessible/", createCanonicalUUIDString().replace('-', '_'));
    Vector<unsigned, 3> registeredObjects;
    registeredObjects.reserveInitialCapacity(interfaces.size());
    for (const auto& interface : interfaces) {
        auto id = g_dbus_connection_register_object(m_connection.get(), path.utf8().data(), interface.first, interface.second, &rootObject, nullptr, nullptr);
        registeredObjects.uncheckedAppend(id);
    }
    m_rootObjects.add(&rootObject, WTFMove(registeredObjects));
    String reference = makeString(uniqueName(), ':', path);
    rootObject.setPath(WTFMove(path));
    completionHandler(reference);
}

void AccessibilityAtspi::unregisterRoot(AccessibilityRootAtspi& rootObject)
{
    if (!m_connection)
        return;

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, rootObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "StateChanged",
        g_variant_new("(siiva{sv})", "defunct", TRUE, 0, g_variant_new_string("0"), nullptr), nullptr);

    auto registeredObjects = m_rootObjects.take(&rootObject);
    g_dbus_connection_emit_signal(m_connection.get(), nullptr, "/org/a11y/atspi/cache", "org.a11y.atspi.Cache", "RemoveAccessible",
        g_variant_new("((so))", uniqueName(), rootObject.path().utf8().data()), nullptr);
    for (auto id : registeredObjects)
        g_dbus_connection_unregister_object(m_connection.get(), id);
}

String AccessibilityAtspi::registerObject(AccessibilityObjectAtspi& atspiObject, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&& interfaces)
{
    RELEASE_ASSERT(!m_isConnecting);
    if (!m_connection)
        return { };

    ensureCache();
    String path = makeString("/org/a11y/atspi/accessible/", createCanonicalUUIDString().replace('-', '_'));
    Vector<unsigned, 20> registeredObjects;
    registeredObjects.reserveInitialCapacity(interfaces.size());
    for (const auto& interface : interfaces) {
        auto id = g_dbus_connection_register_object(m_connection.get(), path.utf8().data(), interface.first, interface.second, &atspiObject, nullptr, nullptr);
        registeredObjects.uncheckedAppend(id);
    }
    m_atspiObjects.add(&atspiObject, WTFMove(registeredObjects));

    return path;
}

void AccessibilityAtspi::unregisterObject(AccessibilityObjectAtspi& atspiObject)
{
    RELEASE_ASSERT(!m_isConnecting);
    if (!m_connection)
        return;

    if (m_atspiHyperlinks.contains(&atspiObject)) {
        auto registeredObjects = m_atspiHyperlinks.take(&atspiObject);
        for (auto id : registeredObjects)
            g_dbus_connection_unregister_object(m_connection.get(), id);
    }

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "StateChanged",
        g_variant_new("(siiva{sv})", "defunct", TRUE, 0, g_variant_new_string("0"), nullptr), nullptr);

    removeAccessible(atspiObject);

    auto registeredObjects = m_atspiObjects.take(&atspiObject);
    for (auto id : registeredObjects)
        g_dbus_connection_unregister_object(m_connection.get(), id);
}

String AccessibilityAtspi::registerHyperlink(AccessibilityObjectAtspi& atspiObject, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&& interfaces)
{
    if (!m_connection)
        return { };

    String path = makeString("/org/a11y/atspi/accessible/", createCanonicalUUIDString().replace('-', '_'));
    Vector<unsigned, 1> registeredObjects;
    registeredObjects.reserveInitialCapacity(interfaces.size());
    for (const auto& interface : interfaces) {
        auto id = g_dbus_connection_register_object(m_connection.get(), path.utf8().data(), interface.first, interface.second, &atspiObject, nullptr, nullptr);
        registeredObjects.uncheckedAppend(id);
    }
    m_atspiHyperlinks.add(&atspiObject, WTFMove(registeredObjects));

    return path;
}

void AccessibilityAtspi::parentChanged(AccessibilityObjectAtspi& atspiObject)
{
    if (!m_connection)
        return;

    // Always emit parentChanged when there are clients because the atspi cache always consumes it.
    if (!m_clients.isEmpty())
        return;

    // Emit parentChanged only if the object is already registered, otherwise register the object,
    // without emitting the signal, because org.a11y.atspi.Cache.AddAccessible() will update the cache.
    if (atspiObject.registerObject())
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "PropertyChange",
        g_variant_new("(siiva{sv})", "accessible-parent", 0, 0, atspiObject.parentReference(), nullptr), nullptr);
}

void AccessibilityAtspi::parentChanged(AccessibilityRootAtspi& rootObject)
{
    if (!m_connection)
        return;

    // Always emit parentChanged when there are clients because the atspi cache always consumes it.
    if (m_clients.isEmpty())
        return;

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, rootObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "PropertyChange",
        g_variant_new("(siiva{sv})", "accessible-parent", 0, 0, rootObject.parentReference(), nullptr), nullptr);
}

void AccessibilityAtspi::childrenChanged(AccessibilityObjectAtspi& atspiObject, AccessibilityObjectAtspi& child, ChildrenChanged change)
{
#if ENABLE(DEVELOPER_MODE)
    notifyChildrenChanged(atspiObject, child, change);
#endif

    if (!m_connection)
        return;

    // Always emit ChildrenChanged when there are clients because the atspi cache always consumes it.
    if (m_clients.isEmpty())
        return;

    addToCacheIfPending(atspiObject);
    addToCacheIfPending(child);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "ChildrenChanged",
        g_variant_new("(siiv(so))", change == ChildrenChanged::Added ? "add" : "remove", child.indexInParentForChildrenChanged(change),
        0, g_variant_new("(so)", uniqueName(), child.path().utf8().data()), uniqueName(), atspiObject.path().utf8().data()), nullptr);
}

void AccessibilityAtspi::childrenChanged(AccessibilityRootAtspi& rootObject, AccessibilityObjectAtspi& child, ChildrenChanged change)
{
    if (!m_connection)
        return;

    // Always emit ChildrenChanged when there are clients because the atspi cache always consumes it.
    if (m_clients.isEmpty())
        return;

    addToCacheIfPending(child);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, rootObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "ChildrenChanged",
        g_variant_new("(siiv(so))", change == ChildrenChanged::Added ? "add" : "remove", 0,
        0, g_variant_new("(so)", uniqueName(), child.path().utf8().data()), uniqueName(), rootObject.path().utf8().data()), nullptr);
}

void AccessibilityAtspi::stateChanged(AccessibilityObjectAtspi& atspiObject, const char* name, bool value)
{
#if ENABLE(DEVELOPER_MODE)
    notifyStateChanged(atspiObject, name, value);
#endif

    if (!m_connection)
        return;

    if (!shouldEmitSignal("Object", "StateChanged", name))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "StateChanged",
        g_variant_new("(siiva{sv})", name, value, 0, g_variant_new_string("0"), nullptr), nullptr);
}

void AccessibilityAtspi::textChanged(AccessibilityObjectAtspi& atspiObject, const char* changeType, CString&& text, unsigned offset, unsigned length)
{
#if ENABLE(DEVELOPER_MODE)
    notifyTextChanged(atspiObject);
#endif

    if (!m_connection)
        return;

    if (!shouldEmitSignal("Object", "TextChanged", changeType))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "TextChanged",
        g_variant_new("(siiva{sv})", changeType, offset, length, g_variant_new_string(text.data()), nullptr), nullptr);
}

void AccessibilityAtspi::textAttributesChanged(AccessibilityObjectAtspi& atspiObject)
{
    if (!m_connection)
        return;

    if (!shouldEmitSignal("Object", "TextAttributesChanged"))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "TextAttributesChanged",
        g_variant_new("(siiva{sv})", "", 0, 0, g_variant_new_string(""), nullptr), nullptr);
}

void AccessibilityAtspi::textCaretMoved(AccessibilityObjectAtspi& atspiObject, unsigned caretOffset)
{
#if ENABLE(DEVELOPER_MODE)
    notifyTextCaretMoved(atspiObject, caretOffset);
#endif

    if (!m_connection)
        return;

    if (!shouldEmitSignal("Object", "TextCaretMoved"))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "TextCaretMoved",
        g_variant_new("(siiva{sv})", "", caretOffset, 0, g_variant_new_string(""), nullptr), nullptr);
}

void AccessibilityAtspi::textSelectionChanged(AccessibilityObjectAtspi& atspiObject)
{
    if (!m_connection)
        return;

    if (!shouldEmitSignal("Object", "TextSelectionChanged"))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "TextSelectionChanged",
        g_variant_new("(siiva{sv})", "", 0, 0, g_variant_new_string(""), nullptr), nullptr);
}

void AccessibilityAtspi::valueChanged(AccessibilityObjectAtspi& atspiObject, double value)
{
#if ENABLE(DEVELOPER_MODE)
    notifyValueChanged(atspiObject);
#endif

    if (!m_connection)
        return;

    if (!shouldEmitSignal("Object", "PropertyChange", "accessible-value"))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "PropertyChange",
        g_variant_new("(siiva{sv})", "accessible-value", 0, 0, g_variant_new_double(value), nullptr), nullptr);
}

void AccessibilityAtspi::selectionChanged(AccessibilityObjectAtspi& atspiObject)
{
#if ENABLE(DEVELOPER_MODE)
    notifySelectionChanged(atspiObject);
#endif

    if (!m_connection)
        return;

    if (!shouldEmitSignal("Object", "SelectionChanged"))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Object", "SelectionChanged",
        g_variant_new("(siiva{sv})", "", 0, 0, g_variant_new_string(""), nullptr), nullptr);
}

void AccessibilityAtspi::loadEvent(AccessibilityObjectAtspi& atspiObject, CString&& event)
{
#if ENABLE(DEVELOPER_MODE)
    notifyLoadEvent(atspiObject, event);
#endif

    if (!m_connection)
        return;

    if (!shouldEmitSignal("Document", event.data()))
        return;

    addToCacheIfPending(atspiObject);

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject.path().utf8().data(), "org.a11y.atspi.Event.Document", event.data(),
        g_variant_new("(siiva{sv})", "", 0, 0, g_variant_new_string(""), nullptr), nullptr);
}

struct RoleNameEntry {
    const char* name;
    const char* localizedName;
};

static constexpr std::pair<AccessibilityRole, RoleNameEntry> roleNames[] = {
    { AccessibilityRole::Application, { "application", N_("application") } },
    { AccessibilityRole::ApplicationAlert, { "notification", N_("notification") } },
    { AccessibilityRole::ApplicationAlertDialog, { "alert", N_("alert") } },
    { AccessibilityRole::ApplicationDialog, { "dialog", N_("dialog") } },
    { AccessibilityRole::ApplicationGroup, { "grouping", N_("grouping") } },
    { AccessibilityRole::ApplicationLog, { "log", N_("log") } },
    { AccessibilityRole::ApplicationMarquee, { "marquee", N_("marquee") } },
    { AccessibilityRole::ApplicationStatus, { "statusbar", N_("statusbar") } },
    { AccessibilityRole::ApplicationTextGroup, { "section", N_("section") } },
    { AccessibilityRole::ApplicationTimer, { "timer", N_("timer") } },
    { AccessibilityRole::Audio, { "audio", N_("audio") } },
    { AccessibilityRole::Blockquote, { "block quote", N_("block quote") } },
    { AccessibilityRole::BusyIndicator, { "progress bar", N_("progress bar") } },
    { AccessibilityRole::Button, { "push button", N_("push button") } },
    { AccessibilityRole::Canvas, { "canvas", N_("canvas") } },
    { AccessibilityRole::Caption, { "caption", N_("caption") } },
    { AccessibilityRole::Cell, { "table cell", N_("table cell") } },
    { AccessibilityRole::CheckBox, { "check box", N_("check box") } },
    { AccessibilityRole::ColorWell, { "push button", N_("push button") } },
    { AccessibilityRole::ColumnHeader, { "column header", N_("column header") } },
    { AccessibilityRole::ComboBox, { "combo box", N_("combo box") } },
    { AccessibilityRole::Definition, { "definition", N_("definition") } },
    { AccessibilityRole::Deletion, { "content deletion", N_("content deletion") } },
    { AccessibilityRole::DescriptionList, { "description list", N_("description list") } },
    { AccessibilityRole::DescriptionListTerm, { "description term", N_("description term") } },
    { AccessibilityRole::DescriptionListDetail, { "description value", N_("description value") } },
    { AccessibilityRole::Directory, { "directory pane", N_("directory pane") } },
    { AccessibilityRole::Div, { "section", N_("section") } },
    { AccessibilityRole::Document, { "document frame", N_("document frame") } },
    { AccessibilityRole::DocumentArticle, { "article", N_("article") } },
    { AccessibilityRole::DocumentMath, { "math", N_("math") } },
    { AccessibilityRole::DocumentNote, { "comment", N_("comment") } },
    { AccessibilityRole::Feed, { "panel", N_("panel") } },
    { AccessibilityRole::Figure, { "panel", N_("panel") } },
    { AccessibilityRole::Footer, { "footer", N_("footer") } },
    { AccessibilityRole::Footnote, { "footnote", N_("footnote") } },
    { AccessibilityRole::Form, { "form", N_("form") } },
    { AccessibilityRole::GraphicsDocument, { "document frame", N_("document frame") } },
    { AccessibilityRole::GraphicsObject, { "panel", N_("panel") } },
    { AccessibilityRole::GraphicsSymbol, { "image", N_("image") } },
    { AccessibilityRole::Grid, { "table", N_("table") } },
    { AccessibilityRole::GridCell, { "table cell", N_("table cell") } },
    { AccessibilityRole::Group, { "panel", N_("panel") } },
    { AccessibilityRole::Heading, { "heading", N_("heading") } },
    { AccessibilityRole::HorizontalRule, { "separator", N_("separator") } },
    { AccessibilityRole::Inline, { "text", N_("text") } },
    { AccessibilityRole::Image, { "image", N_("image") } },
    { AccessibilityRole::ImageMap, { "image map", N_("image map") } },
    { AccessibilityRole::ImageMapLink, { "link", N_("link") } },
    { AccessibilityRole::Insertion, { "content insertion", N_("content insertion") } },
    { AccessibilityRole::Label, { "label", N_("label") } },
    { AccessibilityRole::LandmarkBanner, { "landmark", N_("landmark") } },
    { AccessibilityRole::LandmarkComplementary, { "landmark", N_("landmark") } },
    { AccessibilityRole::LandmarkContentInfo, { "landmark", N_("landmark") } },
    { AccessibilityRole::LandmarkDocRegion, { "landmark", N_("landmark") } },
    { AccessibilityRole::LandmarkMain, { "landmark", N_("landmark") } },
    { AccessibilityRole::LandmarkNavigation, { "landmark", N_("landmark") } },
    { AccessibilityRole::LandmarkRegion, { "landmark", N_("landmark") } },
    { AccessibilityRole::LandmarkSearch, { "landmark", N_("landmark") } },
    { AccessibilityRole::Legend, { "label", N_("label") } },
    { AccessibilityRole::Link, { "link", N_("link") } },
    { AccessibilityRole::List, { "list", N_("list") } },
    { AccessibilityRole::ListBox, { "heading", N_("list box") } },
    { AccessibilityRole::ListBoxOption, { "list item", N_("list item") } },
    { AccessibilityRole::ListItem, { "list item", N_("list item") } },
    { AccessibilityRole::ListMarker, { "text", N_("text") } },
    { AccessibilityRole::Mark, { "mar", N_("mark") } },
    { AccessibilityRole::MathElement, { "math", N_("math") } },
    { AccessibilityRole::Menu, { "menu", N_("menu") } },
    { AccessibilityRole::MenuBar, { "menu bar", N_("menu bar") } },
    { AccessibilityRole::MenuButton, { "menu item", N_("menu item") } },
    { AccessibilityRole::MenuItem, { "menu item", N_("menu item") } },
    { AccessibilityRole::MenuItemCheckbox, { "check menu item", N_("check menu item") } },
    { AccessibilityRole::MenuItemRadio, { "radio menu item", N_("radio menu item") } },
    { AccessibilityRole::MenuListPopup, { "menu", N_("menu") } },
    { AccessibilityRole::MenuListOption, { "menu item", N_("menu item") } },
    { AccessibilityRole::Meter, { "level bar", N_("level bar") } },
    { AccessibilityRole::Outline, { "tree", N_("tree") } },
    { AccessibilityRole::Paragraph, { "paragraph", N_("paragraph") } },
    { AccessibilityRole::PopUpButton, { "combo box", N_("combo box") } },
    { AccessibilityRole::Pre, { "section", N_("section") } },
    { AccessibilityRole::ProgressIndicator, { "progress bar", N_("progress bar") } },
    { AccessibilityRole::RadioButton, { "radio button", N_("radio button") } },
    { AccessibilityRole::RadioGroup, { "panel", N_("panel") } },
    { AccessibilityRole::RowHeader, { "row header", N_("row header") } },
    { AccessibilityRole::Row, { "table row", N_("table row") } },
    { AccessibilityRole::ScrollArea, { "scroll pane", N_("scroll pane") } },
    { AccessibilityRole::ScrollBar, { "scroll bar", N_("scroll bar") } },
    { AccessibilityRole::SearchField, { "entry", N_("entry") } },
    { AccessibilityRole::Slider, { "slider", N_("slider") } },
    { AccessibilityRole::SpinButton, { "spin button", N_("spin button") } },
    { AccessibilityRole::SplitGroup, { "split pane", N_("split pane") } },
    { AccessibilityRole::Splitter, { "separator", N_("separator") } },
    { AccessibilityRole::StaticText, { "text", N_("text") } },
    { AccessibilityRole::Subscript, { "subscript", N_("subscript") } },
    { AccessibilityRole::Superscript, { "superscript", N_("superscript") } },
    { AccessibilityRole::Switch, { "toggle button", N_("toggle button") } },
    { AccessibilityRole::SVGRoot, { "panel", N_("panel") } },
    { AccessibilityRole::SVGText, { "section", N_("section") } },
    { AccessibilityRole::SVGTSpan, { "text", N_("text") } },
    { AccessibilityRole::SVGTextPath, { "text", N_("text") } },
    { AccessibilityRole::TabGroup, { "page tab list", N_("page tab list") } },
    { AccessibilityRole::TabList, { "page tab list", N_("page tab list") } },
    { AccessibilityRole::TabPanel, { "scroll pane", N_("scroll pane") } },
    { AccessibilityRole::Tab, { "page tab", N_("page tab") } },
    { AccessibilityRole::Table, { "table", N_("table") } },
    { AccessibilityRole::Term, { "description term", N_("description term") } },
    { AccessibilityRole::TextArea, { "entry", N_("entry") } },
    { AccessibilityRole::TextField, { "entry", N_("entry") } },
    { AccessibilityRole::TextGroup, { "section", N_("section") } },
    { AccessibilityRole::Time, { "text", N_("text") } },
    { AccessibilityRole::Tree, { "tree", N_("tree") } },
    { AccessibilityRole::TreeGrid, { "tree table", N_("tree table") } },
    { AccessibilityRole::TreeItem, { "tree item", N_("tree item") } },
    { AccessibilityRole::ToggleButton, { "toggle button", N_("toggle button") } },
    { AccessibilityRole::Toolbar, { "tool bar", N_("tool bar") } },
    { AccessibilityRole::Unknown, { "unknown", N_("unknown") } },
    { AccessibilityRole::UserInterfaceTooltip, { "tool tip", N_("tool tip") } },
    { AccessibilityRole::Video, { "video", N_("video") } },
    { AccessibilityRole::WebArea, { "document web", N_("document web") } },
    { AccessibilityRole::WebCoreLink, { "link", N_("link") } },
    { AccessibilityRole::Window, { "window", N_("window") } }
};

const char* AccessibilityAtspi::localizedRoleName(AccessibilityRole role)
{
    static constexpr SortedArrayMap roleNamesMap { roleNames };
    if (auto entry = roleNamesMap.tryGet(role))
        return entry->localizedName;

    return _("unknown");
}

#define ITEM_SIGNATURE "(so)(so)(so)iiassusau"
#define GET_ITEMS_SIGNATURE "a(" ITEM_SIGNATURE ")"

GDBusInterfaceVTable AccessibilityAtspi::s_cacheFunctions = {
    // method_call
    [](GDBusConnection*, const gchar* sender, const gchar*, const gchar*, const gchar* methodName, GVariant*, GDBusMethodInvocation* invocation, gpointer userData) {
        if (!g_strcmp0(methodName, "GetItems")) {
            auto& atspi = *static_cast<AccessibilityAtspi*>(userData);
            atspi.addClient(sender);
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("(" GET_ITEMS_SIGNATURE ")"));
            g_variant_builder_open(&builder, G_VARIANT_TYPE(GET_ITEMS_SIGNATURE));
            for (auto* rootObject : atspi.m_rootObjects.keys()) {
                g_variant_builder_open(&builder, G_VARIANT_TYPE("(" ITEM_SIGNATURE ")"));
                rootObject->serialize(&builder);
                g_variant_builder_close(&builder);
            }

            // We need to call updateBackingStore() on every object before calling serialize()
            // and updating the backing store can detach the object and remove it from the cache.
            auto paths = copyToVector(atspi.m_cache.keys());
            for (const auto& path : paths) {
                auto wrapper = atspi.m_cache.get(path);
                wrapper->updateBackingStore();
                if (!atspi.m_cache.contains(path) || wrapper->isDefunct())
                    continue;
                g_variant_builder_open(&builder, G_VARIANT_TYPE("(" ITEM_SIGNATURE ")"));
                wrapper->serialize(&builder);
                g_variant_builder_close(&builder);
            }

            g_variant_builder_close(&builder);
            g_dbus_method_invocation_return_value(invocation, g_variant_builder_end(&builder));
        }
    },
    // get_property
    [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar* propertyName, GError** error, gpointer) -> GVariant* {
        g_set_error(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Unknown property '%s'", propertyName);
        return nullptr;
    },
    // set_property,
    nullptr,
    // padding
    nullptr
};

void AccessibilityAtspi::ensureCache()
{
    if (m_cacheID || !m_connection)
        return;

    m_cacheID = g_dbus_connection_register_object(m_connection.get(), "/org/a11y/atspi/cache", const_cast<GDBusInterfaceInfo*>(&webkit_cache_interface), &s_cacheFunctions, this, nullptr, nullptr);
}

void AccessibilityAtspi::addToCacheIfNeeded(AccessibilityObjectAtspi& atspiObject)
{
    atspiObject.updateBackingStore();
    if (atspiObject.isDefunct())
        return;

    auto addResult = m_cache.add(atspiObject.path(), &atspiObject);
    if (!addResult.isNewEntry)
        return;

    GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("(" ITEM_SIGNATURE ")"));
    atspiObject.serialize(&builder);
    g_dbus_connection_emit_signal(m_connection.get(), nullptr, "/org/a11y/atspi/cache", "org.a11y.atspi.Cache", "AddAccessible",
        g_variant_new("(@(" ITEM_SIGNATURE "))", g_variant_builder_end(&builder)), nullptr);
}

void AccessibilityAtspi::addToCacheIfPending(AccessibilityObjectAtspi& atspiObject)
{
    if (!m_cacheUpdateList.remove(&atspiObject))
        return;

    addToCacheIfNeeded(atspiObject);
    if (m_cacheUpdateList.isEmpty())
        m_cacheUpdateTimer.stop();
}

void AccessibilityAtspi::cacheUpdateTimerFired()
{
    while (!m_cacheUpdateList.isEmpty())
        addToCacheIfNeeded(*m_cacheUpdateList.takeFirst());
}

void AccessibilityAtspi::addAccessible(AccessibilityObjectAtspi& atspiObject)
{
    if (!m_connection)
        return;

    m_cacheUpdateList.add(&atspiObject);
    if (!m_cacheUpdateTimer.isActive())
        m_cacheUpdateTimer.startOneShot(0_s);
}

void AccessibilityAtspi::removeAccessible(AccessibilityObjectAtspi& atspiObject)
{
    if (m_cacheUpdateList.remove(&atspiObject))
        return;

    const auto& path = atspiObject.path();
    if (!m_cache.remove(path))
        return;

    g_dbus_connection_emit_signal(m_connection.get(), nullptr, "/org/a11y/atspi/cache", "org.a11y.atspi.Cache", "RemoveAccessible",
        g_variant_new("((so))", uniqueName(), path.utf8().data()), nullptr);
}

void AccessibilityAtspi::cacheClearTimerFired()
{
    for (const auto& registeredObjects : m_atspiHyperlinks.values()) {
        for (auto id : registeredObjects)
            g_dbus_connection_unregister_object(m_connection.get(), id);
    }
    m_atspiHyperlinks.clear();
    for (const auto& it : m_atspiObjects) {
        for (auto id : it.value)
            g_dbus_connection_unregister_object(m_connection.get(), id);

        it.key->didUnregisterObject();
    }
    m_atspiObjects.clear();
    m_cache.clear();

    RELEASE_ASSERT(m_cacheUpdateList.isEmpty());
    m_cacheUpdateTimer.stop();
    m_cacheClearTimer.stop();
}

namespace Accessibility {

PlatformRoleMap createPlatformRoleMap()
{
    PlatformRoleMap roleMap;
    for (const auto& entry : roleNames)
        roleMap.add(static_cast<unsigned>(entry.first), String::fromUTF8(entry.second.name));
    return roleMap;
}

} // namespace Accessibility

#if ENABLE(DEVELOPER_MODE)
void AccessibilityAtspi::addNotificationObserver(void* context, NotificationObserver&& observer)
{
    m_notificationObservers.add(context, WTFMove(observer));
}

void AccessibilityAtspi::removeNotificationObserver(void* context)
{
    m_notificationObservers.remove(context);
}

void AccessibilityAtspi::notifyStateChanged(AccessibilityObjectAtspi& atspiObject, const char* name, bool value) const
{
    if (m_notificationObservers.isEmpty())
        return;

    auto notificationName = [&](const char* name) -> const char* {
        if (!g_strcmp0(name, "checked"))
            return "CheckedStateChanged";
        if (!g_strcmp0(name, "invalid-entry"))
            return "AXInvalidStatusChanged";
        if (!g_strcmp0(name, "active"))
            return "ActiveStateChanged";
        if (!g_strcmp0(name, "busy"))
            return "AXElementBusyChanged";
        if (!g_strcmp0(name, "enabled"))
            return "AXDisabledStateChanged";
        if (!g_strcmp0(name, "expanded"))
            return "AXExpandedChanged";
        if (!g_strcmp0(name, "pressed"))
            return "AXPressedStateChanged";
        if (!g_strcmp0(name, "read-only"))
            return "AXReadOnlyStatusChanged";
        if (!g_strcmp0(name, "required"))
            return "AXRequiredStatusChanged";
        if (!g_strcmp0(name, "sensitive"))
            return "AXSensitiveStateChanged";
        if (!g_strcmp0(name, "focused") && value)
            return "AXFocusedUIElementChanged";

        return nullptr;
    };

    const char* notification = notificationName(name);
    if (!notification)
        return;

    for (const auto& observer : m_notificationObservers.values())
        observer(atspiObject, notification, value);
}

void AccessibilityAtspi::notifySelectionChanged(AccessibilityObjectAtspi& atspiObject) const
{
    for (const auto& observer : m_notificationObservers.values())
        observer(atspiObject, "AXSelectedChildrenChanged", nullptr);
}

void AccessibilityAtspi::notifyTextChanged(AccessibilityObjectAtspi& atspiObject) const
{
    for (const auto& observer : m_notificationObservers.values())
        observer(atspiObject, "AXTextChanged", nullptr);
}

void AccessibilityAtspi::notifyTextCaretMoved(AccessibilityObjectAtspi& atspiObject, unsigned caretOffset) const
{
    for (const auto& observer : m_notificationObservers.values())
        observer(atspiObject, "AXTextCaretMoved", caretOffset);
}

void AccessibilityAtspi::notifyChildrenChanged(AccessibilityObjectAtspi& atspiObject, AccessibilityObjectAtspi& child, ChildrenChanged change) const
{
    const char* notification = change == ChildrenChanged::Added ? "AXChildrenAdded" : "AXChildrenRemoved";
    for (const auto& observer : m_notificationObservers.values())
        observer(atspiObject, notification, child);
}

void AccessibilityAtspi::notifyValueChanged(AccessibilityObjectAtspi& atspiObject) const
{
    for (const auto& observer : m_notificationObservers.values())
        observer(atspiObject, "AXValueChanged", nullptr);
}

void AccessibilityAtspi::notifyLoadEvent(AccessibilityObjectAtspi& atspiObject, const CString& event) const
{
    if (event != "LoadComplete")
        return;

    for (const auto& observer : m_notificationObservers.values())
        observer(atspiObject, "AXLoadComplete", nullptr);
}

#endif

} // namespace WebCore

#endif // ENABLE(ACCESSIBILITY) && USE(ATSPI)
