/*
 * 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 ENABLE(ACCESSIBILITY) && USE(ATSPI)
#include "AccessibilityAtspiEnums.h"
#include "AccessibilityObjectInterface.h"
#include "AccessibilityRootAtspi.h"
#include "AccessibilityTableCell.h"
#include "ElementInlines.h"
#include "RenderAncestorIterator.h"
#include "RenderBlock.h"
#include "RenderObject.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::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
};

AccessibilityRootAtspi* AccessibilityObjectAtspi::root()
{
    if (!m_root) {
        if (auto* document = m_coreObject->document())
            m_root = document->page()->accessibilityRootObject();
    }
    return m_root;
}

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));
    AccessibilityAtspi::singleton().addAccessible(*this);

    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() || !root())
        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")
        addState(Atspi::State::InvalidEntry);

    if (m_coreObject->supportsAutoComplete() && m_coreObject->autoCompleteValue() != "none")
        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", "WebKitGTK");
#elif PLATFORM(WPE)
    map.add("toolkit", "WPEWebKit");
#endif
    if (!m_coreObject)
        return map;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (m_coreObject->supportsSetSize())
        map.add("setsize", 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", "ascending");
            break;
        case AccessibilitySortDirection::Descending:
            map.add("sort", "descending");
            break;
        case AccessibilitySortDirection::Other:
            map.add("sort", "other");
            break;
        case AccessibilitySortDirection::None:
            map.add("sort", "none");
            break;
        }
    }

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

    String valueDescription = m_coreObject->valueDescription();
    if (!valueDescription.isEmpty())
        map.add("valuetext", 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 ATK, 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", roleString);

    String computedRoleString = m_coreObject->computedRoleString();
    if (!computedRoleString.isEmpty()) {
        map.add("computed-role", 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", computedRoleString);
    }

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

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

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

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

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

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

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

    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())
        m_coreObject->ariaLabelledByElements(ariaLabelledByElements);
    addRelation(Atspi::LabelledBy, ariaLabelledByElements);

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

    AccessibilityObject::AccessibilityChildrenVector ariaFlowToElements;
    m_coreObject->ariaFlowToElements(ariaFlowToElements);
    addRelation(Atspi::FlowsTo, ariaFlowToElements);

    AccessibilityObject::AccessibilityChildrenVector ariaFlowToReferencingElements;
    m_coreObject->ariaFlowToReferencingElements(ariaFlowToReferencingElements);
    addRelation(Atspi::FlowsFrom, ariaFlowToReferencingElements);

    AccessibilityObject::AccessibilityChildrenVector ariaDescribedByElements;
    m_coreObject->ariaDescribedByElements(ariaDescribedByElements);
    addRelation(Atspi::DescribedBy, ariaDescribedByElements);

    AccessibilityObject::AccessibilityChildrenVector ariaDescribedByReferencingElements;
    m_coreObject->ariaDescribedByReferencingElements(ariaDescribedByReferencingElements);
    addRelation(Atspi::DescriptionFor, ariaDescribedByReferencingElements);

    AccessibilityObject::AccessibilityChildrenVector ariaControlsElements;
    m_coreObject->ariaControlsElements(ariaControlsElements);
    addRelation(Atspi::ControllerFor, ariaControlsElements);

    AccessibilityObject::AccessibilityChildrenVector ariaControlsReferencingElements;
    m_coreObject->ariaControlsReferencingElements(ariaControlsReferencingElements);
    addRelation(Atspi::ControlledBy, ariaControlsReferencingElements);

    AccessibilityObject::AccessibilityChildrenVector ariaOwnsElements;
    m_coreObject->ariaOwnsElements(ariaOwnsElements);
    addRelation(Atspi::NodeParentOf, ariaOwnsElements);

    AccessibilityObject::AccessibilityChildrenVector ariaOwnsReferencingElements;
    m_coreObject->ariaOwnsReferencingElements(ariaOwnsReferencingElements);
    addRelation(Atspi::NodeChildOf, ariaOwnsReferencingElements);

    AccessibilityObject::AccessibilityChildrenVector ariaDetailsElements;
    m_coreObject->ariaDetailsElements(ariaDetailsElements);
    addRelation(Atspi::Details, ariaDetailsElements);

    AccessibilityObject::AccessibilityChildrenVector ariaDetailsReferencingElements;
    m_coreObject->ariaDetailsReferencingElements(ariaDetailsReferencingElements);
    addRelation(Atspi::DetailsFor, ariaDetailsReferencingElements);

    AccessibilityObject::AccessibilityChildrenVector ariaErrorMessageElements;
    m_coreObject->ariaErrorMessageElements(ariaErrorMessageElements);
    addRelation(Atspi::ErrorMessage, ariaErrorMessageElements);

    AccessibilityObject::AccessibilityChildrenVector ariaErrorMessageReferencingElements;
    m_coreObject->ariaErrorMessageReferencingElements(ariaErrorMessageReferencingElements);
    addRelation(Atspi::ErrorFor, ariaErrorMessageReferencingElements);

    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());
    g_variant_builder_add(builder, "i", childCount());

    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
{
    switch (m_coreObject->roleValue()) {
    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";
    case Atspi::Role::Text:
    case Atspi::Role::Static:
        return "text";
    case Atspi::Role::InvalidRole:
        return "invalid";
    case Atspi::Role::Panel:
        return "panel";
    case Atspi::Role::Table:
        return "table";
    case Atspi::Role::TableRow:
        return "table row";
    case Atspi::Role::TableCell:
        return "table cell";
    case Atspi::Role::Section:
        return "section";
    case Atspi::Role::MathFraction:
        return "math fraction";
    case Atspi::Role::MathRoot:
        return "math root";
    case Atspi::Role::Subscript:
        return "subscript";
    case Atspi::Role::Superscript:
        return "superscript";
    default:
        break;
    }

    RELEASE_ASSERT_NOT_REACHED();
}

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

    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::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);
    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();
}

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;

    return AccessibilityObjectInclusion::DefaultBehavior;
}

} // namespace WebCore

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