/*
 * Copyright (C) 2021 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 "AccessibilityObjectAtspi.h"

#if USE(ATSPI)
#include "AXObjectCache.h"
#include "AccessibilityAtspiEnums.h"
#include "AccessibilityAtspiInterfaces.h"
#include "AccessibilityObjectInterface.h"
#include "AccessibilityRootAtspi.h"
#include "AccessibilityTableCell.h"
#include "ElementInlines.h"
#include "HTMLSpanElement.h"
#include "RenderAncestorIterator.h"
#include "RenderBlock.h"
#include "RenderInline.h"
#include "RenderObject.h"
#include "RenderTableCell.h"
#include "RenderText.h"
#include "TextControlInnerElements.h"
#include "TextIterator.h"
#include <glib/gi18n-lib.h>
#include <wtf/UUID.h>

namespace WebCore {

Ref<AccessibilityObjectAtspi> AccessibilityObjectAtspi::create(AXCoreObject* coreObject, AccessibilityRootAtspi* root)
{
    return adoptRef(*new AccessibilityObjectAtspi(coreObject, root));
}

static inline bool roleIsTextType(AccessibilityRole role)
{
    return role == AccessibilityRole::Paragraph
        || role == AccessibilityRole::Heading
        || role == AccessibilityRole::Div
        || role == AccessibilityRole::Cell
        || role == AccessibilityRole::Link
        || role == AccessibilityRole::WebCoreLink
        || role == AccessibilityRole::ListItem
        || role == AccessibilityRole::Pre
        || role == AccessibilityRole::GridCell
        || role == AccessibilityRole::TextGroup
        || role == AccessibilityRole::ApplicationTextGroup
        || role == AccessibilityRole::ApplicationGroup;
}

OptionSet<AccessibilityObjectAtspi::Interface> AccessibilityObjectAtspi::interfacesForObject(AXCoreObject& coreObject)
{
    OptionSet<Interface> interfaces = { Interface::Accessible, Interface::Component, Interface::Action };

    RenderObject* renderer = coreObject.isAccessibilityRenderObject() ? coreObject.renderer() : nullptr;
    if (coreObject.roleValue() == AccessibilityRole::StaticText || coreObject.roleValue() == AccessibilityRole::ColorWell)
        interfaces.add(Interface::Text);
    else if (coreObject.isTextControl() || coreObject.isNonNativeTextControl())
        interfaces.add(Interface::Text);
    else if (!coreObject.isWebArea()) {
        if (coreObject.roleValue() != AccessibilityRole::Table) {
            interfaces.add(Interface::Hypertext);
            if ((renderer && renderer->childrenInline()) || roleIsTextType(coreObject.roleValue()) || coreObject.isMathToken())
                interfaces.add(Interface::Text);
        }
    }

    if (coreObject.supportsRangeValue())
        interfaces.add(Interface::Value);

    if (coreObject.isLink() || (isRendererReplacedElement(renderer)))
        interfaces.add(Interface::Hyperlink);

    if (coreObject.roleValue() == AccessibilityRole::WebArea)
        interfaces.add(Interface::Document);

    if (coreObject.isImage())
        interfaces.add(Interface::Image);

    if (coreObject.canHaveSelectedChildren())
        interfaces.add(Interface::Selection);

    if (coreObject.isTable())
        interfaces.add(Interface::Table);

    if (coreObject.roleValue() == AccessibilityRole::Cell
        || coreObject.roleValue() == AccessibilityRole::GridCell
        || coreObject.roleValue() == AccessibilityRole::ColumnHeader
        || coreObject.roleValue() == AccessibilityRole::RowHeader)
        interfaces.add(Interface::TableCell);

    if (coreObject.roleValue() == AccessibilityRole::ListMarker && renderer) {
        if (renderer->isImage())
            interfaces.add(Interface::Image);
        else
            interfaces.add(Interface::Text);
        interfaces.add(Interface::Hyperlink);
    }

    return interfaces;
}

AccessibilityObjectAtspi::AccessibilityObjectAtspi(AXCoreObject* coreObject, AccessibilityRootAtspi* root)
    : m_coreObject(coreObject)
    , m_interfaces(interfacesForObject(*m_coreObject))
    , m_root(root)
{
}

void AccessibilityObjectAtspi::cacheDestroyed()
{
    m_coreObject = nullptr;
    if (!m_isRegistered)
        return;

    if (m_parent && !*m_parent && m_root)
        m_root->childRemoved(*this);

    AccessibilityAtspi::singleton().unregisterObject(*this);
}

void AccessibilityObjectAtspi::elementDestroyed()
{
    m_coreObject = nullptr;
    if (!m_isRegistered)
        return;

    if (m_parent) {
        if (*m_parent)
            m_parent.value()->childRemoved(*this);
        else if (m_root)
            m_root->childRemoved(*this);
    }

    AccessibilityAtspi::singleton().unregisterObject(*this);
}

static unsigned atspiRole(AccessibilityRole role)
{
    switch (role) {
    case AccessibilityRole::Annotation:
    case AccessibilityRole::ApplicationAlert:
        return Atspi::Role::Notification;
    case AccessibilityRole::ApplicationAlertDialog:
        return Atspi::Role::Alert;
    case AccessibilityRole::ApplicationDialog:
        return Atspi::Role::Dialog;
    case AccessibilityRole::ApplicationStatus:
        return Atspi::Role::StatusBar;
    case AccessibilityRole::Unknown:
        return Atspi::Role::Unknown;
    case AccessibilityRole::Audio:
        return Atspi::Role::Audio;
    case AccessibilityRole::Video:
        return Atspi::Role::Video;
    case AccessibilityRole::Button:
        return Atspi::Role::PushButton;
    case AccessibilityRole::Switch:
    case AccessibilityRole::ToggleButton:
        return Atspi::Role::ToggleButton;
    case AccessibilityRole::RadioButton:
        return Atspi::Role::RadioButton;
    case AccessibilityRole::CheckBox:
        return Atspi::Role::CheckBox;
    case AccessibilityRole::Slider:
        return Atspi::Role::Slider;
    case AccessibilityRole::TabGroup:
    case AccessibilityRole::TabList:
        return Atspi::Role::PageTabList;
    case AccessibilityRole::TextField:
    case AccessibilityRole::TextArea:
    case AccessibilityRole::SearchField:
        return Atspi::Role::Entry;
    case AccessibilityRole::StaticText:
        return Atspi::Role::Static;
    case AccessibilityRole::Outline:
    case AccessibilityRole::Tree:
        return Atspi::Role::Tree;
    case AccessibilityRole::TreeItem:
        return Atspi::Role::TreeItem;
    case AccessibilityRole::MenuBar:
        return Atspi::Role::MenuBar;
    case AccessibilityRole::MenuListPopup:
    case AccessibilityRole::Menu:
        return Atspi::Role::Menu;
    case AccessibilityRole::MenuListOption:
    case AccessibilityRole::MenuItem:
    case AccessibilityRole::MenuButton:
        return Atspi::Role::MenuItem;
    case AccessibilityRole::MenuItemCheckbox:
        return Atspi::Role::CheckMenuItem;
    case AccessibilityRole::MenuItemRadio:
        return Atspi::Role::RadioMenuItem;
    case AccessibilityRole::Column:
        return Atspi::Role::Unknown; // There's no TableColumn in atspi.
    case AccessibilityRole::Row:
        return Atspi::Role::TableRow;
    case AccessibilityRole::Toolbar:
        return Atspi::Role::ToolBar;
    case AccessibilityRole::Meter:
        return Atspi::Role::LevelBar;
    case AccessibilityRole::BusyIndicator:
    case AccessibilityRole::ProgressIndicator:
        return Atspi::Role::ProgressBar;
    case AccessibilityRole::Window:
        return Atspi::Role::Window;
    case AccessibilityRole::PopUpButton:
    case AccessibilityRole::ComboBox:
        return Atspi::Role::ComboBox;
    case AccessibilityRole::SplitGroup:
        return Atspi::Role::SplitPane;
    case AccessibilityRole::Splitter:
        return Atspi::Role::Separator;
    case AccessibilityRole::ColorWell:
        return Atspi::Role::PushButton;
    case AccessibilityRole::List:
        return Atspi::Role::List;
    case AccessibilityRole::ScrollBar:
        return Atspi::Role::ScrollBar;
    case AccessibilityRole::ScrollArea:
    case AccessibilityRole::TabPanel:
        return Atspi::Role::ScrollPane;
    case AccessibilityRole::Grid:
    case AccessibilityRole::Table:
        return Atspi::Role::Table;
    case AccessibilityRole::TreeGrid:
        return Atspi::Role::TreeTable;
    case AccessibilityRole::Application:
        return Atspi::Role::Application;
    case AccessibilityRole::ApplicationGroup:
    case AccessibilityRole::Feed:
    case AccessibilityRole::Figure:
    case AccessibilityRole::GraphicsObject:
    case AccessibilityRole::Group:
    case AccessibilityRole::RadioGroup:
    case AccessibilityRole::SVGRoot:
        return Atspi::Role::Panel;
    case AccessibilityRole::RowHeader:
        return Atspi::Role::RowHeader;
    case AccessibilityRole::ColumnHeader:
        return Atspi::Role::ColumnHeader;
    case AccessibilityRole::Caption:
        return Atspi::Role::Caption;
    case AccessibilityRole::Cell:
    case AccessibilityRole::GridCell:
        return Atspi::Role::TableCell;
    case AccessibilityRole::Link:
    case AccessibilityRole::WebCoreLink:
    case AccessibilityRole::ImageMapLink:
        return Atspi::Role::Link;
    case AccessibilityRole::ImageMap:
        return Atspi::Role::ImageMap;
    case AccessibilityRole::GraphicsSymbol:
    case AccessibilityRole::Image:
        return Atspi::Role::Image;
    case AccessibilityRole::DocumentArticle:
        return Atspi::Role::Article;
    case AccessibilityRole::Document:
    case AccessibilityRole::GraphicsDocument:
        return Atspi::Role::DocumentFrame;
    case AccessibilityRole::DocumentNote:
        return Atspi::Role::Comment;
    case AccessibilityRole::Heading:
        return Atspi::Role::Heading;
    case AccessibilityRole::ListBox:
        return Atspi::Role::ListBox;
    case AccessibilityRole::ListItem:
    case AccessibilityRole::ListBoxOption:
        return Atspi::Role::ListItem;
    case AccessibilityRole::Paragraph:
        return Atspi::Role::Paragraph;
    case AccessibilityRole::Label:
    case AccessibilityRole::Legend:
        return Atspi::Role::Label;
    case AccessibilityRole::Blockquote:
        return Atspi::Role::BlockQuote;
    case AccessibilityRole::Footnote:
        return Atspi::Role::Footnote;
    case AccessibilityRole::ApplicationTextGroup:
    case AccessibilityRole::Div:
    case AccessibilityRole::Pre:
    case AccessibilityRole::SVGText:
    case AccessibilityRole::TextGroup:
        return Atspi::Role::Section;
    case AccessibilityRole::Footer:
        return Atspi::Role::Footer;
    case AccessibilityRole::Form:
        return Atspi::Role::Form;
    case AccessibilityRole::Canvas:
        return Atspi::Role::Canvas;
    case AccessibilityRole::HorizontalRule:
        return Atspi::Role::Separator;
    case AccessibilityRole::SpinButton:
        return Atspi::Role::SpinButton;
    case AccessibilityRole::Tab:
        return Atspi::Role::PageTab;
    case AccessibilityRole::UserInterfaceTooltip:
        return Atspi::Role::ToolTip;
    case AccessibilityRole::WebArea:
        return Atspi::Role::DocumentWeb;
    case AccessibilityRole::WebApplication:
        return Atspi::Role::Embedded;
    case AccessibilityRole::ApplicationLog:
        return Atspi::Role::Log;
    case AccessibilityRole::ApplicationMarquee:
        return Atspi::Role::Marquee;
    case AccessibilityRole::ApplicationTimer:
        return Atspi::Role::Timer;
    case AccessibilityRole::Definition:
        return Atspi::Role::Definition;
    case AccessibilityRole::DocumentMath:
        return Atspi::Role::Math;
    case AccessibilityRole::LandmarkBanner:
    case AccessibilityRole::LandmarkComplementary:
    case AccessibilityRole::LandmarkContentInfo:
    case AccessibilityRole::LandmarkDocRegion:
    case AccessibilityRole::LandmarkMain:
    case AccessibilityRole::LandmarkNavigation:
    case AccessibilityRole::LandmarkRegion:
    case AccessibilityRole::LandmarkSearch:
        return Atspi::Role::Landmark;
    case AccessibilityRole::DescriptionList:
        return Atspi::Role::DescriptionList;
    case AccessibilityRole::Term:
    case AccessibilityRole::DescriptionListTerm:
        return Atspi::Role::DescriptionTerm;
    case AccessibilityRole::DescriptionListDetail:
        return Atspi::Role::DescriptionValue;
    case AccessibilityRole::Deletion:
        return Atspi::Role::ContentDeletion;
    case AccessibilityRole::Insertion:
        return Atspi::Role::ContentInsertion;
    case AccessibilityRole::Subscript:
        return Atspi::Role::Subscript;
    case AccessibilityRole::Superscript:
        return Atspi::Role::Superscript;
    case AccessibilityRole::Inline:
    case AccessibilityRole::SVGTextPath:
    case AccessibilityRole::SVGTSpan:
    case AccessibilityRole::Time:
        return Atspi::Role::Static;
    case AccessibilityRole::Directory:
        return Atspi::Role::DirectoryPane;
    case AccessibilityRole::Mark:
        return Atspi::Role::Mark;
    case AccessibilityRole::Browser:
    case AccessibilityRole::Details:
    case AccessibilityRole::DisclosureTriangle:
    case AccessibilityRole::Drawer:
    case AccessibilityRole::EditableText:
    case AccessibilityRole::GrowArea:
    case AccessibilityRole::HelpTag:
    case AccessibilityRole::Ignored:
    case AccessibilityRole::Incrementor:
    case AccessibilityRole::Matte:
    case AccessibilityRole::Model:
    case AccessibilityRole::Presentational:
    case AccessibilityRole::RowGroup:
    case AccessibilityRole::RubyBase:
    case AccessibilityRole::RubyBlock:
    case AccessibilityRole::RubyInline:
    case AccessibilityRole::RubyRun:
    case AccessibilityRole::RubyText:
    case AccessibilityRole::Ruler:
    case AccessibilityRole::RulerMarker:
    case AccessibilityRole::Sheet:
    case AccessibilityRole::SliderThumb:
    case AccessibilityRole::SpinButtonPart:
    case AccessibilityRole::Summary:
    case AccessibilityRole::SystemWide:
    case AccessibilityRole::TableHeaderContainer:
    case AccessibilityRole::ValueIndicator:
        return Atspi::Role::Unknown;
    case AccessibilityRole::ListMarker:
    case AccessibilityRole::MathElement:
        RELEASE_ASSERT_NOT_REACHED();
    }

    RELEASE_ASSERT_NOT_REACHED();
}

GDBusInterfaceVTable AccessibilityObjectAtspi::s_accessibleFunctions = {
    // method_call
    [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) {
        auto atspiObject = Ref { *static_cast<AccessibilityObjectAtspi*>(userData) };
        atspiObject->updateBackingStore();

        if (!g_strcmp0(methodName, "GetRole"))
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(u)", atspiObject->role()));
        else if (!g_strcmp0(methodName, "GetRoleName"))
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", atspiObject->roleName().utf8().data()));
        else if (!g_strcmp0(methodName, "GetLocalizedRoleName"))
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", atspiObject->localizedRoleName()));
        else if (!g_strcmp0(methodName, "GetState")) {
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("(au)"));

            auto states = atspiObject->state();
            g_variant_builder_open(&builder, G_VARIANT_TYPE("au"));
            g_variant_builder_add(&builder, "u", static_cast<uint32_t>(states & 0xffffffff));
            g_variant_builder_add(&builder, "u", static_cast<uint32_t>(states >> 32));
            g_variant_builder_close(&builder);

            g_dbus_method_invocation_return_value(invocation, g_variant_builder_end(&builder));
        } else if (!g_strcmp0(methodName, "GetAttributes")) {
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("(a{ss})"));

            g_variant_builder_open(&builder, G_VARIANT_TYPE("a{ss}"));
            atspiObject->buildAttributes(&builder);
            g_variant_builder_close(&builder);

            g_dbus_method_invocation_return_value(invocation, g_variant_builder_end(&builder));
        } else if (!g_strcmp0(methodName, "GetApplication"))
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(@(so))", AccessibilityAtspi::singleton().applicationReference()));
        else if (!g_strcmp0(methodName, "GetChildAtIndex")) {
            int index;
            g_variant_get(parameters, "(i)", &index);
            auto* wrapper = index >= 0 ? atspiObject->childAt(index) : nullptr;
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(@(so))", wrapper ? wrapper->reference() : AccessibilityAtspi::singleton().nullReference()));
        } else if (!g_strcmp0(methodName, "GetChildren")) {
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("a(so)"));
            for (const auto& wrapper : atspiObject->children())
                g_variant_builder_add(&builder, "@(so)", wrapper->reference());
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(a(so))", &builder));
        } else if (!g_strcmp0(methodName, "GetIndexInParent")) {
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", atspiObject->indexInParent()));
        } else if (!g_strcmp0(methodName, "GetRelationSet")) {
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("a(ua(so))"));
            atspiObject->buildRelationSet(&builder);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(a(ua(so)))", &builder));
        } else if (!g_strcmp0(methodName, "GetInterfaces")) {
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("as"));
            atspiObject->buildInterfaces(&builder);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(as)", &builder));
        }
    },
    // get_property
    [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar* propertyName, GError** error, gpointer userData) -> GVariant* {
        auto atspiObject = Ref { *static_cast<AccessibilityObjectAtspi*>(userData) };
        atspiObject->updateBackingStore();

        if (!g_strcmp0(propertyName, "Name"))
            return g_variant_new_string(atspiObject->name().data());
        if (!g_strcmp0(propertyName, "Description"))
            return g_variant_new_string(atspiObject->description().data());
        if (!g_strcmp0(propertyName, "Locale"))
            return g_variant_new_string(atspiObject->locale().utf8().data());
        if (!g_strcmp0(propertyName, "AccessibleId"))
            return g_variant_new_string(atspiObject->m_coreObject ? String::number(atspiObject->m_coreObject->objectID().toUInt64()).utf8().data() : "");
        if (!g_strcmp0(propertyName, "Parent"))
            return atspiObject->parentReference();
        if (!g_strcmp0(propertyName, "ChildCount"))
            return g_variant_new_int32(atspiObject->childCount());

        g_set_error(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Unknown property '%s'", propertyName);
        return nullptr;
    },
    // set_property,
    nullptr,
    // padding
    { nullptr }
};

bool AccessibilityObjectAtspi::registerObject()
{
    if (!m_path.isNull())
        return false;

    m_isRegistered = true;
    Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>> interfaces;
    if (m_interfaces.contains(Interface::Accessible))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_accessible_interface), &s_accessibleFunctions });
    if (m_interfaces.contains(Interface::Component))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_component_interface), &s_componentFunctions });
    if (m_interfaces.contains(Interface::Text))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_text_interface), &s_textFunctions });
    if (m_interfaces.contains(Interface::Value))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_value_interface), &s_valueFunctions });
    if (m_interfaces.contains(Interface::Hyperlink))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions });
    if (m_interfaces.contains(Interface::Hypertext))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hypertext_interface), &s_hypertextFunctions });
    if (m_interfaces.contains(Interface::Action))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_action_interface), &s_actionFunctions });
    if (m_interfaces.contains(Interface::Document))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_document_interface), &s_documentFunctions });
    if (m_interfaces.contains(Interface::Image))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_image_interface), &s_imageFunctions });
    if (m_interfaces.contains(Interface::Selection))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_selection_interface), &s_selectionFunctions });
    if (m_interfaces.contains(Interface::Table))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_table_interface), &s_tableFunctions });
    if (m_interfaces.contains(Interface::TableCell))
        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_table_cell_interface), &s_tableCellFunctions });

    m_path = AccessibilityAtspi::singleton().registerObject(*this, WTFMove(interfaces));
    return true;
}

void AccessibilityObjectAtspi::didUnregisterObject()
{
    m_isRegistered = false;
    m_path = { };
}

const String& AccessibilityObjectAtspi::path()
{
    registerObject();
    return m_path;
}

GVariant* AccessibilityObjectAtspi::reference()
{
    return g_variant_new("(so)", AccessibilityAtspi::singleton().uniqueName(), path().utf8().data());
}

GVariant* AccessibilityObjectAtspi::hyperlinkReference()
{
    if (m_hyperlinkPath.isNull()) {
        registerObject();
        m_hyperlinkPath = AccessibilityAtspi::singleton().registerHyperlink(*this, { { const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions } });
    }

    return g_variant_new("(so)", AccessibilityAtspi::singleton().uniqueName(), m_hyperlinkPath.utf8().data());
}

void AccessibilityObjectAtspi::setParent(std::optional<AccessibilityObjectAtspi*> atspiParent)
{
    if (m_parent == atspiParent)
        return;

    m_parent = atspiParent;
    if (!m_coreObject || m_coreObject->accessibilityIsIgnored())
        return;

    AccessibilityAtspi::singleton().parentChanged(*this);
    if (m_parent) {
        if (*m_parent)
            m_parent.value()->childAdded(*this);
        else if (m_root)
            m_root->childAdded(*this);
    }
}

std::optional<AccessibilityObjectAtspi*> AccessibilityObjectAtspi::parent() const
{
    if (!m_coreObject)
        return std::nullopt;

    auto* axParent = m_coreObject->parentObjectUnignored();
    if (!axParent)
        return nullptr;

    if (auto* atspiParent = axParent->wrapper())
        return atspiParent;

    return std::nullopt;
}

GVariant* AccessibilityObjectAtspi::parentReference() const
{
    if (m_parent) {
        if (*m_parent)
            return m_parent.value()->reference();

        if (m_root)
            return m_root->reference();
    }

    return AccessibilityAtspi::singleton().nullReference();
}

unsigned AccessibilityObjectAtspi::childCount() const
{
    return m_coreObject ? m_coreObject->children().size() : 0;
}

AccessibilityObjectAtspi* AccessibilityObjectAtspi::childAt(unsigned index) const
{
    if (!m_coreObject)
        return nullptr;

    const auto& children = m_coreObject->children();
    if (index >= children.size())
        return nullptr;

    return children[index]->wrapper();
}

Vector<RefPtr<AccessibilityObjectAtspi>> AccessibilityObjectAtspi::wrapperVector(const Vector<RefPtr<AXCoreObject>>& elements) const
{
    Vector<RefPtr<AccessibilityObjectAtspi>> wrappers;
    wrappers.reserveInitialCapacity(elements.size());
    for (const auto& element : elements) {
        if (auto* wrapper = element->wrapper())
            wrappers.uncheckedAppend(wrapper);
    }
    return wrappers;
}

Vector<RefPtr<AccessibilityObjectAtspi>> AccessibilityObjectAtspi::children() const
{
    if (!m_coreObject)
        return { };

    return wrapperVector(m_coreObject->children());
}

int AccessibilityObjectAtspi::indexInParent() const
{
    if (!m_coreObject) {
        m_indexInParent = -1;
        return m_indexInParent;
    }

    auto* axParent = m_coreObject->parentObjectUnignored();
    if (!axParent) {
        m_indexInParent = 0;
        return m_indexInParent;
    }

    const auto& children = axParent->children();
    unsigned index = 0;
    for (const auto& child : children) {
        if (child.get() == m_coreObject) {
            m_indexInParent = index;
            return m_indexInParent;
        }
        index++;
    }

    m_indexInParent = -1;
    return m_indexInParent;
}

int AccessibilityObjectAtspi::indexInParentForChildrenChanged(AccessibilityAtspi::ChildrenChanged change)
{
    if (change == AccessibilityAtspi::ChildrenChanged::Removed)
        return m_indexInParent;

    updateBackingStore();
    return indexInParent();
}

CString AccessibilityObjectAtspi::name() const
{
    if (!m_coreObject)
        return "";

    if (m_coreObject->roleValue() == AccessibilityRole::ListBoxOption || m_coreObject->roleValue() == AccessibilityRole::MenuListOption) {
        auto value = m_coreObject->stringValue();
        if (!value.isEmpty())
            return value.utf8();
    }

    Vector<AccessibilityText> textOrder;
    m_coreObject->accessibilityText(textOrder);

    for (const auto& text : textOrder) {
        // FIXME: This check is here because AccessibilityNodeObject::titleElementText()
        // appends an empty String for the LabelByElementText source when there is a
        // titleUIElement(). Removing this check makes some fieldsets lose their name.
        if (text.text.isEmpty())
            continue;

        // WebCore Accessibility should provide us with the text alternative computation
        // in the order defined by that spec. So take the first thing that our platform
        // does not expose via the AtkObject description.
        if (text.textSource != AccessibilityTextSource::Help && text.textSource != AccessibilityTextSource::Summary)
            return text.text.utf8();
    }

    return "";
}

CString AccessibilityObjectAtspi::description() const
{
    if (!m_coreObject)
        return "";

    Vector<AccessibilityText> textOrder;
    m_coreObject->accessibilityText(textOrder);

    bool nameTextAvailable = false;
    for (const auto& text : textOrder) {
        // WebCore Accessibility should provide us with the text alternative computation
        // in the order defined by that spec. So take the first thing that our platform
        // does not expose via the AtkObject name.
        if (text.textSource == AccessibilityTextSource::Help || text.textSource == AccessibilityTextSource::Summary)
            return text.text.utf8();

        // If there is no other text alternative, the title tag contents will have been
        // used for the AtkObject name. We don't want to duplicate it here.
        if (text.textSource == AccessibilityTextSource::TitleTag && nameTextAvailable)
            return text.text.utf8();

        nameTextAvailable = true;
    }

    return "";
}

String AccessibilityObjectAtspi::locale() const
{
    return m_coreObject ? m_coreObject->language() : String();
}

static bool shouldIncludeOrientationState(const AXCoreObject& coreObject)
{
    return coreObject.isComboBox()
        || coreObject.isRadioGroup()
        || coreObject.isTreeGrid()
        || coreObject.isScrollbar()
        || coreObject.isListBox()
        || coreObject.isMenu()
        || coreObject.isTree()
        || coreObject.isMenuBar()
        || coreObject.isSplitter()
        || coreObject.isTabList()
        || coreObject.isToolbar()
        || coreObject.isSlider();
}

uint64_t AccessibilityObjectAtspi::state() const
{
    uint64_t states = 0;

    auto addState = [&](Atspi::State atspiState) {
        states |= (G_GUINT64_CONSTANT(1) << atspiState);
    };

    if (!m_coreObject) {
        addState(Atspi::State::Defunct);
        return states;
    }

    if (m_coreObject->isEnabled()) {
        addState(Atspi::State::Enabled);
        addState(Atspi::State::Sensitive);
    }

    if (m_coreObject->isVisible()) {
        addState(Atspi::State::Visible);
        if (!m_coreObject->isOffScreen())
            addState(Atspi::State::Showing);
    }

    if (m_coreObject->isSelectedOptionActive() || m_coreObject->currentState() != AccessibilityCurrentState::False)
        addState(Atspi::State::Active);

    if (m_coreObject->canSetFocusAttribute())
        addState(Atspi::State::Focusable);

    if (m_coreObject->isFocused() && !m_coreObject->activeDescendant())
        addState(Atspi::State::Focused);
    else if (m_coreObject->isActiveDescendantOfFocusedContainer()) {
        addState(Atspi::State::Focusable);
        addState(Atspi::State::Focused);
    }

    if (m_coreObject->canSetValueAttribute()) {
        if (m_coreObject->supportsChecked())
            addState(Atspi::State::Checkable);

        if (m_coreObject->isTextControl() || m_coreObject->isNonNativeTextControl())
            addState(Atspi::State::Editable);
    } else if (m_coreObject->supportsReadOnly())
        addState(Atspi::State::ReadOnly);

    if (m_coreObject->isChecked())
        addState(Atspi::State::Checked);

    if (m_coreObject->isPressed())
        addState(Atspi::State::Pressed);

    if (m_coreObject->isRequired())
        addState(Atspi::State::Required);

    if (m_coreObject->roleValue() == AccessibilityRole::TextArea || m_coreObject->ariaIsMultiline())
        addState(Atspi::State::MultiLine);
    else if (m_coreObject->roleValue() == AccessibilityRole::TextField || m_coreObject->roleValue() == AccessibilityRole::SearchField)
        addState(Atspi::State::SingleLine);

    if (m_coreObject->isTextControl())
        addState(Atspi::State::SelectableText);

    if (m_coreObject->canSetSelectedAttribute())
        addState(Atspi::State::Selectable);

    if (m_coreObject->isMultiSelectable())
        addState(Atspi::State::Multiselectable);

    if (m_coreObject->isSelected())
        addState(Atspi::State::Selected);

    if (m_coreObject->canSetExpandedAttribute())
        addState(Atspi::State::Expandable);

    if (m_coreObject->isExpanded())
        addState(Atspi::State::Expanded);

    if (m_coreObject->hasPopup())
        addState(Atspi::State::HasPopup);

    if (shouldIncludeOrientationState(*m_coreObject)) {
        switch (m_coreObject->orientation()) {
        case AccessibilityOrientation::Horizontal:
            addState(Atspi::State::Horizontal);
            break;
        case AccessibilityOrientation::Vertical:
            addState(Atspi::State::Vertical);
            break;
        case AccessibilityOrientation::Undefined:
            break;
        }
    }

    if (m_coreObject->isIndeterminate())
        addState(Atspi::State::Indeterminate);
    else if ((m_coreObject->isCheckboxOrRadio() || m_coreObject->isMenuItem() || m_coreObject->isToggleButton()) && m_coreObject->checkboxOrRadioValue() == AccessibilityButtonState::Mixed)
        addState(Atspi::State::Indeterminate);

    if (m_coreObject->isModalNode())
        addState(Atspi::State::Modal);

    if (m_coreObject->isBusy())
        addState(Atspi::State::Busy);

    if (m_coreObject->invalidStatus() != "false"_s)
        addState(Atspi::State::InvalidEntry);

    if (m_coreObject->supportsAutoComplete() && m_coreObject->autoCompleteValue() != "none"_s)
        addState(Atspi::State::SupportsAutocompletion);

    return states;
}

bool AccessibilityObjectAtspi::isDefunct() const
{
    return !m_coreObject;
}

String AccessibilityObjectAtspi::id() const
{
    if (!m_coreObject)
        return { };

    if (auto* element = m_coreObject->element())
        return element->getIdAttribute().string();

    return { };
}

HashMap<String, String> AccessibilityObjectAtspi::attributes() const
{
    HashMap<String, String> map;
#if PLATFORM(GTK)
    map.add("toolkit"_s, "WebKitGTK"_s);
#elif PLATFORM(WPE)
    map.add("toolkit"_s, "WPEWebKit"_s);
#endif
    if (!m_coreObject)
        return map;

    String tagName = m_coreObject->tagName();
    if (!tagName.isEmpty())
        map.add("tag"_s, tagName);

    if (auto* element = m_coreObject->element()) {
        String id = element->getIdAttribute().string();
        if (!id.isEmpty())
            map.add("id"_s, id);
    }

    int level = m_coreObject->isHeading() ? m_coreObject->headingLevel() : m_coreObject->hierarchicalLevel();
    if (level)
        map.add("level"_s, String::number(level));

    int rowCount = m_coreObject->axRowCount();
    if (rowCount)
        map.add("rowcount"_s, String::number(rowCount));

    int columnCount = m_coreObject->axColumnCount();
    if (columnCount)
        map.add("colcount"_s, String::number(columnCount));

    int rowIndex = m_coreObject->axRowIndex();
    if (rowIndex != -1)
        map.add("rowindex"_s, String::number(rowIndex));

    int columnIndex = m_coreObject->axColumnIndex();
    if (columnIndex != -1)
        map.add("colindex"_s, String::number(columnIndex));

    if (is<AccessibilityTableCell>(m_coreObject)) {
        auto& cell = downcast<AccessibilityTableCell>(*m_coreObject);
        int rowSpan = cell.axRowSpan();
        if (rowSpan != -1)
            map.add("rowspan"_s, String::number(rowSpan));

        int columnSpan = cell.axColumnSpan();
        if (columnSpan != -1)
            map.add("colspan"_s, String::number(columnSpan));
    }

    String placeholder = m_coreObject->placeholderValue();
    if (!placeholder.isEmpty())
        map.add("placeholder-text"_s, placeholder);

    if (m_coreObject->supportsAutoComplete())
        map.add("autocomplete"_s, m_coreObject->autoCompleteValue());

    if (m_coreObject->supportsHasPopup())
        map.add("haspopup"_s, m_coreObject->popupValue());

    if (m_coreObject->supportsCurrent())
        map.add("current"_s, m_coreObject->currentValue());

    if (m_coreObject->supportsPosInSet())
        map.add("posinset"_s, String::number(m_coreObject->posInSet()));

    if (m_coreObject->supportsSetSize())
        map.add("setsize"_s, String::number(m_coreObject->setSize()));

    // The Core AAM states that an explicitly-set value should be exposed, including "none".
    if (static_cast<AccessibilityObject*>(m_coreObject)->hasAttribute(HTMLNames::aria_sortAttr)) {
        switch (m_coreObject->sortDirection()) {
        case AccessibilitySortDirection::Invalid:
            break;
        case AccessibilitySortDirection::Ascending:
            map.add("sort"_s, "ascending"_s);
            break;
        case AccessibilitySortDirection::Descending:
            map.add("sort"_s, "descending"_s);
            break;
        case AccessibilitySortDirection::Other:
            map.add("sort"_s, "other"_s);
            break;
        case AccessibilitySortDirection::None:
            map.add("sort"_s, "none"_s);
            break;
        }
    }

    String isReadOnly = m_coreObject->readOnlyValue();
    if (!isReadOnly.isEmpty())
        map.add("readonly"_s, isReadOnly);

    String valueDescription = m_coreObject->valueDescription();
    if (!valueDescription.isEmpty())
        map.add("valuetext"_s, valueDescription);

    // According to the W3C Core Accessibility API Mappings 1.1, section 5.4.1 General Rules:
    // "User agents must expose the WAI-ARIA role string if the API supports a mechanism to do so."
    // In the case of ATSPI, the mechanism to do so is an object attribute pair (xml-roles:"string").
    // We cannot use the computedRoleString for this purpose because it is not limited to elements
    // with ARIA roles, and it might not contain the actual ARIA role value (e.g. DPub ARIA).
    String roleString = static_cast<AccessibilityObject*>(m_coreObject)->getAttribute(HTMLNames::roleAttr);
    if (!roleString.isEmpty())
        map.add("xml-roles"_s, roleString);

    String computedRoleString = m_coreObject->computedRoleString();
    if (!computedRoleString.isEmpty()) {
        map.add("computed-role"_s, computedRoleString);

        // The HTML AAM maps several elements to ARIA landmark roles. In order for the type of landmark
        // to be obtainable in the same fashion as an ARIA landmark, fall back on the computedRoleString.
        // We also want to do this for the style-format-group element types so that the type of format
        // group it is doesn't get lost to a generic platform role.
        if (m_coreObject->ariaRoleAttribute() == AccessibilityRole::Unknown && (m_coreObject->isLandmark() || m_coreObject->isStyleFormatGroup()))
            map.set("xml-roles"_s, computedRoleString);
    }

    String roleDescription = m_coreObject->roleDescription();
    if (!roleDescription.isEmpty())
        map.add("roledescription"_s, roleDescription);

    String dropEffect = static_cast<AccessibilityObject*>(m_coreObject)->getAttribute(HTMLNames::aria_dropeffectAttr);
    if (!dropEffect.isEmpty())
        map.add("dropeffect"_s, dropEffect);

    if (m_coreObject->supportsDragging())
        map.add("grabbed"_s, m_coreObject->isGrabbed() ? "true"_s : "false"_s);

    String keyShortcuts = m_coreObject->keyShortcutsValue();
    if (!keyShortcuts.isEmpty())
        map.add("keyshortcuts"_s, keyShortcuts);

    if (m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PreSuperscript) || m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PreSubscript))
        map.add("multiscript-type"_s, "pre"_s);
    else if (m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PostSuperscript) || m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PostSubscript))
        map.add("multiscript-type"_s, "post"_s);

    if (auto* liveContainer = m_coreObject->liveRegionAncestor(false)) {
        auto liveStatus = liveContainer->liveRegionStatus();
        map.add("container-live"_s, liveStatus);
        auto relevant = liveContainer->liveRegionRelevant();
        map.add("container-relevant"_s, relevant);
        bool isAtomic = liveContainer->liveRegionAtomic();
        if (isAtomic)
            map.add("container-atomic"_s, "true"_s);
        const String& liveRole = roleString.isEmpty() ? computedRoleString : roleString;
        if (!liveRole.isEmpty())
            map.add("container-live-role"_s, liveRole);

        if (liveContainer == m_coreObject) {
            map.add("live"_s, liveStatus);
            map.add("relevant"_s, relevant);
            if (isAtomic)
                map.add("atomic"_s, "true"_s);
        } else if (!isAtomic && m_coreObject->liveRegionAtomic())
            map.add("atomic"_s, "true"_s);
    }

    return map;
}

void AccessibilityObjectAtspi::buildAttributes(GVariantBuilder* builder) const
{
    for (const auto& it : attributes())
        g_variant_builder_add(builder, "{ss}", it.key.utf8().data(), it.value.utf8().data());
}

HashMap<uint32_t, Vector<RefPtr<AccessibilityObjectAtspi>>> AccessibilityObjectAtspi::relationMap() const
{
    HashMap<uint32_t, Vector<RefPtr<AccessibilityObjectAtspi>>> map;
    if (!m_coreObject)
        return map;

    auto addRelation = [&](Atspi::Relation relation, const AccessibilityObject::AccessibilityChildrenVector& children) {
        Vector<RefPtr<AccessibilityObjectAtspi>> wrappers;
        for (const auto& child : children) {
            if (auto* wrapper = child->wrapper())
                wrappers.append(wrapper);
        }
        if (!wrappers.isEmpty())
            map.add(relation, WTFMove(wrappers));
    };

    AccessibilityObject::AccessibilityChildrenVector ariaLabelledByElements;
    if (m_coreObject->isControl()) {
        if (auto* label = m_coreObject->correspondingLabelForControlElement())
            ariaLabelledByElements.append(label);
    } else if (m_coreObject->isFieldset()) {
        if (auto* label = m_coreObject->titleUIElement())
            ariaLabelledByElements.append(label);
    } else if (m_coreObject->roleValue() == AccessibilityRole::Legend) {
        if (auto* renderFieldset = ancestorsOfType<RenderBlock>(*m_coreObject->renderer()).first()) {
            if (renderFieldset->isFieldset())
                ariaLabelledByElements.append(m_coreObject->axObjectCache()->getOrCreate(renderFieldset));
        }
    } else if (!m_coreObject->correspondingControlForLabelElement())
        ariaLabelledByElements = m_coreObject->labelledByObjects();
    addRelation(Atspi::LabelledBy, ariaLabelledByElements);

    AccessibilityObject::AccessibilityChildrenVector labelForObjects;
    if (auto* control = m_coreObject->correspondingControlForLabelElement())
        labelForObjects.append(control);
    else
        labelForObjects = m_coreObject->labelForObjects();
    addRelation(Atspi::LabelFor, labelForObjects);

    addRelation(Atspi::FlowsTo, m_coreObject->flowToObjects());
    addRelation(Atspi::FlowsFrom, m_coreObject->flowFromObjects());

    addRelation(Atspi::DescribedBy, m_coreObject->describedByObjects());
    addRelation(Atspi::DescriptionFor, m_coreObject->descriptionForObjects());

    addRelation(Atspi::ControllerFor, m_coreObject->controlledObjects());
    addRelation(Atspi::ControlledBy, m_coreObject->controllers());

    addRelation(Atspi::NodeParentOf, m_coreObject->ownedObjects());
    addRelation(Atspi::NodeChildOf, m_coreObject->owners());

    addRelation(Atspi::Details, m_coreObject->detailedByObjects());
    addRelation(Atspi::DetailsFor, m_coreObject->detailsForObjects());

    addRelation(Atspi::ErrorMessage, m_coreObject->errorMessageObjects());
    addRelation(Atspi::ErrorFor, m_coreObject->errorMessageForObjects());

    return map;
}

void AccessibilityObjectAtspi::buildRelationSet(GVariantBuilder* builder) const
{
    for (const auto& it : relationMap()) {
        GVariantBuilder arrayBuilder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("a(so)"));
        for (const auto& atspiObject : it.value)
            g_variant_builder_add(&arrayBuilder, "@(so)", atspiObject->reference());
        g_variant_builder_add(builder, "(ua(so))", it.key, &arrayBuilder);
    }
}

void AccessibilityObjectAtspi::buildInterfaces(GVariantBuilder* builder) const
{
    if (m_interfaces.contains(Interface::Accessible))
        g_variant_builder_add(builder, "s", webkit_accessible_interface.name);
    if (m_interfaces.contains(Interface::Component))
        g_variant_builder_add(builder, "s", webkit_component_interface.name);
    if (m_interfaces.contains(Interface::Text))
        g_variant_builder_add(builder, "s", webkit_text_interface.name);
    if (m_interfaces.contains(Interface::Value))
        g_variant_builder_add(builder, "s", webkit_value_interface.name);
    if (m_interfaces.contains(Interface::Hyperlink))
        g_variant_builder_add(builder, "s", webkit_hyperlink_interface.name);
    if (m_interfaces.contains(Interface::Hypertext))
        g_variant_builder_add(builder, "s", webkit_hypertext_interface.name);
    if (m_interfaces.contains(Interface::Action))
        g_variant_builder_add(builder, "s", webkit_action_interface.name);
    if (m_interfaces.contains(Interface::Document))
        g_variant_builder_add(builder, "s", webkit_document_interface.name);
    if (m_interfaces.contains(Interface::Image))
        g_variant_builder_add(builder, "s", webkit_image_interface.name);
    if (m_interfaces.contains(Interface::Selection))
        g_variant_builder_add(builder, "s", webkit_selection_interface.name);
    if (m_interfaces.contains(Interface::Table))
        g_variant_builder_add(builder, "s", webkit_table_interface.name);
    if (m_interfaces.contains(Interface::TableCell))
        g_variant_builder_add(builder, "s", webkit_table_cell_interface.name);
}

void AccessibilityObjectAtspi::serialize(GVariantBuilder* builder) const
{
    g_variant_builder_add(builder, "(so)", AccessibilityAtspi::singleton().uniqueName(), m_path.utf8().data());
    g_variant_builder_add(builder, "@(so)", AccessibilityAtspi::singleton().applicationReference());
    g_variant_builder_add(builder, "@(so)", parentReference());

    g_variant_builder_add(builder, "i", indexInParent());
    // Do not set the children count in cache, because children are handled by children-changed signals.
    g_variant_builder_add(builder, "i", -1);

    GVariantBuilder interfaces = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("as"));
    buildInterfaces(&interfaces);
    g_variant_builder_add(builder, "@as", g_variant_new("as", &interfaces));

    g_variant_builder_add(builder, "s", name().data());

    g_variant_builder_add(builder, "u", role());

    g_variant_builder_add(builder, "s", description().data());

    GVariantBuilder states = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("au"));
    auto atspiStates = state();
    g_variant_builder_add(&states, "u", static_cast<uint32_t>(atspiStates & 0xffffffff));
    g_variant_builder_add(&states, "u", static_cast<uint32_t>(atspiStates >> 32));
    g_variant_builder_add(builder, "@au", g_variant_builder_end(&states));
}

void AccessibilityObjectAtspi::childAdded(AccessibilityObjectAtspi& child)
{
    if (!m_isRegistered)
        return;

    if (!m_coreObject || m_coreObject->accessibilityIsIgnored())
        return;

    AccessibilityAtspi::singleton().childrenChanged(*this, child, AccessibilityAtspi::ChildrenChanged::Added);
}

void AccessibilityObjectAtspi::childRemoved(AccessibilityObjectAtspi& child)
{
    if (!m_isRegistered)
        return;

    AccessibilityAtspi::singleton().childrenChanged(*this, child, AccessibilityAtspi::ChildrenChanged::Removed);
}

void AccessibilityObjectAtspi::stateChanged(const char* name, bool value)
{
    AccessibilityAtspi::singleton().stateChanged(*this, name, value);
}

void AccessibilityObjectAtspi::loadEvent(const char* event)
{
    AccessibilityAtspi::singleton().loadEvent(*this, event);
}

std::optional<unsigned> AccessibilityObjectAtspi::effectiveRole() const
{
    if (m_coreObject->isPasswordField())
        return Atspi::Role::PasswordText;

    switch (m_coreObject->roleValue()) {
    case AccessibilityRole::Form:
        if (m_coreObject->ariaRoleAttribute() != AccessibilityRole::Unknown)
            return Atspi::Role::Landmark;
        break;
    case AccessibilityRole::ListMarker: {
        auto* renderer = m_coreObject->renderer();
        return renderer && renderer->isImage() ? Atspi::Role::Image : Atspi::Role::Text;
    }
    case AccessibilityRole::MathElement:
        if (m_coreObject->isMathRow())
            return Atspi::Role::Panel;
        if (m_coreObject->isMathTable())
            return Atspi::Role::Table;
        if (m_coreObject->isMathTableRow())
            return Atspi::Role::TableRow;
        if (m_coreObject->isMathTableCell())
            return Atspi::Role::TableCell;
        if (m_coreObject->isMathSubscriptSuperscript() || m_coreObject->isMathMultiscript())
            return Atspi::Role::Section;
        if (m_coreObject->isMathFraction())
            return Atspi::Role::MathFraction;
        if (m_coreObject->isMathSquareRoot() || m_coreObject->isMathRoot())
            return Atspi::Role::MathRoot;
        if (m_coreObject->isMathScriptObject(AccessibilityMathScriptObjectType::Subscript)
            || m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PreSubscript)
            || m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PostSubscript))
            return Atspi::Role::Subscript;
        if (m_coreObject->isMathScriptObject(AccessibilityMathScriptObjectType::Superscript)
            || m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PreSuperscript)
            || m_coreObject->isMathMultiscriptObject(AccessibilityMathMultiscriptObjectType::PostSuperscript))
            return Atspi::Role::Superscript;
        if (m_coreObject->isMathToken())
            return Atspi::Role::Static;
        break;
    case AccessibilityRole::ListItem: {
        if (m_coreObject->inheritsPresentationalRole())
            return Atspi::Role::Section;
        break;
    }
    default:
        break;
    }

    return std::nullopt;
}

unsigned AccessibilityObjectAtspi::role() const
{
    if (!m_coreObject)
        return Atspi::Role::InvalidRole;

    if (auto effective = effectiveRole())
        return *effective;

    return atspiRole(m_coreObject->roleValue());
}

String AccessibilityObjectAtspi::effectiveRoleName() const
{
    auto effective = effectiveRole();
    if (!effective)
        return { };

    switch (*effective) {
    case Atspi::Role::Image:
        return "image"_s;
    case Atspi::Role::Text:
    case Atspi::Role::Static:
        return "text"_s;
    case Atspi::Role::InvalidRole:
        return "invalid"_s;
    case Atspi::Role::Panel:
        return "panel"_s;
    case Atspi::Role::PasswordText:
        return "password text"_s;
    case Atspi::Role::Table:
        return "table"_s;
    case Atspi::Role::TableRow:
        return "table row"_s;
    case Atspi::Role::TableCell:
        return "table cell"_s;
    case Atspi::Role::Section:
        return "section"_s;
    case Atspi::Role::MathFraction:
        return "math fraction"_s;
    case Atspi::Role::MathRoot:
        return "math root"_s;
    case Atspi::Role::Subscript:
        return "subscript"_s;
    case Atspi::Role::Superscript:
        return "superscript"_s;
    case Atspi::Role::Landmark:
        return "landmark"_s;
    default:
        break;
    }

    RELEASE_ASSERT_NOT_REACHED();
}

String AccessibilityObjectAtspi::roleName() const
{
    if (!m_coreObject)
        return "invalid"_s;

    auto effective = effectiveRoleName();
    if (!effective.isEmpty())
        return effective;

    return m_coreObject->rolePlatformString();
}

const char* AccessibilityObjectAtspi::effectiveLocalizedRoleName() const
{
    auto effective = effectiveRole();
    if (!effective)
        return nullptr;

    switch (*effective) {
    case Atspi::Role::Image:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Image);
    case Atspi::Role::Text:
    case Atspi::Role::Static:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::StaticText);
    case Atspi::Role::InvalidRole:
        return _("invalid");
    case Atspi::Role::Panel:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Group);
    case Atspi::Role::PasswordText:
        return _("password text");
    case Atspi::Role::Table:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Table);
    case Atspi::Role::TableRow:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Row);
    case Atspi::Role::TableCell:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Cell);
    case Atspi::Role::Section:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Div);
    case Atspi::Role::MathFraction:
        return _("math fraction");
    case Atspi::Role::MathRoot:
        return _("math root");
    case Atspi::Role::Subscript:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Subscript);
    case Atspi::Role::Superscript:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::Superscript);
    case Atspi::Role::Landmark:
        return AccessibilityAtspi::localizedRoleName(AccessibilityRole::LandmarkMain);
    default:
        break;
    }

    RELEASE_ASSERT_NOT_REACHED();
}

const char* AccessibilityObjectAtspi::localizedRoleName() const
{
    if (!m_coreObject)
        return _("invalid");

    if (const auto* effective = effectiveLocalizedRoleName())
        return effective;

    return AccessibilityAtspi::localizedRoleName(m_coreObject->roleValue());
}

void AccessibilityObjectAtspi::updateBackingStore()
{
    if (m_coreObject)
        m_coreObject->updateBackingStore();
}

bool AccessibilityObjectAtspi::isIgnored() const
{
    return m_coreObject ? m_coreObject->accessibilityIsIgnored() : true;
}

void AccessibilityObject::detachPlatformWrapper(AccessibilityDetachmentType detachmentType)
{
    switch (detachmentType) {
    case AccessibilityDetachmentType::CacheDestroyed:
        wrapper()->cacheDestroyed();
        break;
    case AccessibilityDetachmentType::ElementDestroyed:
        wrapper()->elementDestroyed();
        break;
    case AccessibilityDetachmentType::ElementChanged:
        RELEASE_ASSERT_NOT_REACHED();
        break;
    }
}

bool AccessibilityObject::accessibilityIgnoreAttachment() const
{
    return false;
}

AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
{
    auto* parent = parentObject();
    if (!parent)
        return AccessibilityObjectInclusion::DefaultBehavior;

    // If the author has provided a role, platform-specific inclusion likely doesn't apply.
    if (ariaRoleAttribute() != AccessibilityRole::Unknown)
        return AccessibilityObjectInclusion::DefaultBehavior;

    // Never expose an unknown object, since AT's won't know what to
    // do with them. This is what is done on the Mac as well.
    if (roleValue() == AccessibilityRole::Unknown)
        return AccessibilityObjectInclusion::IgnoreObject;

    // The object containing the text should implement org.a11y.atspi.Text itself.
    if (roleValue() == AccessibilityRole::StaticText)
        return AccessibilityObjectInclusion::IgnoreObject;

    // Entries and password fields have extraneous children which we want to ignore.
    if (parent->isPasswordField() || parent->isTextControl())
        return AccessibilityObjectInclusion::IgnoreObject;

    // We expose the slider as a whole but not its value indicator.
    if (roleValue() == AccessibilityRole::SliderThumb)
        return AccessibilityObjectInclusion::IgnoreObject;

    // List items inheriting presentational are ignored, but their content exposed.
    // Since we expose text in the parent, we need to expose presentational list items
    // with a different role (section).
    if (roleValue() == AccessibilityRole::ListItem && inheritsPresentationalRole())
        return AccessibilityObjectInclusion::IncludeObject;

    RenderObject* renderObject = renderer();
    if (!renderObject)
        return AccessibilityObjectInclusion::DefaultBehavior;

    // We always want to include paragraphs that have rendered content.
    // WebCore Accessibility does so unless there is a RenderBlock child.
    if (roleValue() == AccessibilityRole::Paragraph) {
        auto child = childrenOfType<RenderBlock>(downcast<RenderElement>(*renderObject)).first();
        return child ? AccessibilityObjectInclusion::IncludeObject : AccessibilityObjectInclusion::DefaultBehavior;
    }

    // We always want to include table cells (layout and CSS) that have rendered text content.
    if (is<RenderTableCell>(renderObject)) {
        for (const auto& child : childrenOfType<RenderObject>(downcast<RenderElement>(*renderObject))) {
            if (is<RenderInline>(child) || is<RenderText>(child) || is<HTMLSpanElement>(child.node()))
                return AccessibilityObjectInclusion::IncludeObject;
        }
        return AccessibilityObjectInclusion::DefaultBehavior;
    }

    if (renderObject->isAnonymousBlock()) {
        // The text displayed by an ARIA menu item is exposed through the accessible name.
        if (parent->isMenuItem())
            return AccessibilityObjectInclusion::IgnoreObject;

        // The text displayed in headings is typically exposed in the heading itself.
        if (parent->isHeading())
            return AccessibilityObjectInclusion::IgnoreObject;

        // The text displayed in list items is typically exposed in the list item itself.
        if (parent->isListItem())
            return AccessibilityObjectInclusion::IgnoreObject;

        // The text displayed in links is typically exposed in the link itself.
        if (parent->isLink())
            return AccessibilityObjectInclusion::IgnoreObject;

        // FIXME: This next one needs some further consideration. But paragraphs are not
        // typically huge (like divs). And ignoring anonymous block children of paragraphs
        // will preserve existing behavior.
        if (parent->roleValue() == AccessibilityRole::Paragraph)
            return AccessibilityObjectInclusion::IgnoreObject;

        return AccessibilityObjectInclusion::DefaultBehavior;
    }

    Node* node = renderObject->node();
    if (!node)
        return AccessibilityObjectInclusion::DefaultBehavior;

    // We don't want <span> elements to show up in the accessibility hierarchy unless
    // we have good reasons for that (e.g. focusable or visible because of containing
    // a meaningful accessible name, maybe set through ARIA).
    if (is<HTMLSpanElement>(node) && !canSetFocusAttribute() && !hasAttributesRequiredForInclusion() && !supportsARIAAttributes())
        return AccessibilityObjectInclusion::IgnoreObject;

    if (is<TextControlInnerTextElement>(node))
        return AccessibilityObjectInclusion::IgnoreObject;

    return AccessibilityObjectInclusion::DefaultBehavior;
}

} // namespace WebCore

#endif // USE(ATSPI)
