/*
 * Copyright (C) 2021 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "AccessibilityUIElement.h"

#if ENABLE(ACCESSIBILITY) && USE(ATSPI)
#include "AccessibilityNotificationHandler.h"
#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/OpaqueJSString.h>
#include <WebCore/AccessibilityAtspiEnums.h>
#include <WebCore/AccessibilityObjectAtspi.h>
#include <WebKit/WKBundleFrame.h>
#include <wtf/HashSet.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/URL.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringToIntegerConversion.h>
#include <wtf/unicode/CharacterNames.h>

namespace WTR {

RefPtr<AccessibilityController> AccessibilityUIElement::s_controller;

AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
    : m_element(element)
{
    if (!s_controller)
        s_controller = InjectedBundle::singleton().accessibilityController();
}

AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
    : JSWrappable()
    , m_element(other.m_element)
{
}

AccessibilityUIElement::~AccessibilityUIElement()
{
}

bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
{
    return otherElement && m_element.get() == otherElement->platformUIElement();
}

void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement> >& children)
{
}

void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >& children, unsigned location, unsigned length)
{
}

int AccessibilityUIElement::childrenCount()
{
    m_element->updateBackingStore();
    return m_element->childCount();
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
{
    m_element->updateBackingStore();
    auto* element = m_element->hitTest({ x, y }, WebCore::Atspi::CoordinateType::WindowCoordinates);
    return AccessibilityUIElement::create(element ? element : m_element.get());
}

unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
{
    return 0;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
{
    m_element->updateBackingStore();
    if (auto* child = m_element->childAt(index))
        return AccessibilityUIElement::create(child);
    return nullptr;
}

static RefPtr<AccessibilityUIElement> elementForRelationAtIndex(WebCore::AccessibilityObjectAtspi* element, WebCore::Atspi::Relation relation, unsigned index)
{
    element->updateBackingStore();
    auto relationMap = element->relationMap();
    auto targets = relationMap.get(relation);
    if (targets.isEmpty() || index >= targets.size())
        return nullptr;

    auto target = targets[index];
    if (!target)
        return nullptr;

    return AccessibilityUIElement::create(target.get());
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
{
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
{
    return elementForRelationAtIndex(m_element.get(), WebCore::Atspi::Relation::NodeParentOf, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
{
    return elementForRelationAtIndex(m_element.get(), WebCore::Atspi::Relation::FlowsTo, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsElementAtIndex(unsigned index)
{
    return elementForRelationAtIndex(m_element.get(), WebCore::Atspi::Relation::ControllerFor, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
{
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return nullptr;

    m_element->updateBackingStore();
    auto rows = m_element->rows();
    if (index >= rows.size())
        return nullptr;

    return AccessibilityUIElement::create(rows[index].get());
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Selection))
        return nullptr;

    m_element->updateBackingStore();
    if (auto* selectedChild = m_element->selectedChild(index))
        return AccessibilityUIElement::create(selectedChild);
    return nullptr;
}

unsigned AccessibilityUIElement::selectedChildrenCount() const
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Selection))
        return 0;

    m_element->updateBackingStore();
    return m_element->selectionCount();
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
{
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
{
    return elementForRelationAtIndex(m_element.get(), WebCore::Atspi::Relation::LabelledBy, 0);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
{
    m_element->updateBackingStore();
    if (auto* parent = m_element->parent().value_or(nullptr))
        return AccessibilityUIElement::create(parent);
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

static String attributesOfElement(AccessibilityUIElement& element)
{
    StringBuilder builder;

    builder.append(element.role()->string(), '\n');

    builder.append("AXParent: ");
    if (auto parent = element.parentElement()) {
        builder.append(parent->role()->string().substring(8));
        auto parentName = parent->title()->string().substring(9);
        if (!parentName.isEmpty())
            builder.append(": ", parentName);
    } else
        builder.append("(null)");
    builder.append('\n');

    builder.append("AXChildren: ", element.childrenCount(), '\n');

    builder.append("AXPosition:  { ", FormattedNumber::fixedPrecision(element.x(), 6, KeepTrailingZeros));
    builder.append(", ", FormattedNumber::fixedPrecision(element.y(), 6, KeepTrailingZeros));
    builder.append(" }\n");

    builder.append("AXSize: { ", FormattedNumber::fixedPrecision(element.width(), 6, KeepTrailingZeros));
    builder.append(", ", FormattedNumber::fixedPrecision(element.height(), 6, KeepTrailingZeros));
    builder.append(" }\n");

    String title = element.title()->string();
    if (!title.isEmpty()) {
        builder.append(title);
        builder.append('\n');
    }

    String description = element.description()->string();
    if (!description.isEmpty())
        builder.append(description.utf8().data(), '\n');

    String value = element.stringValue()->string();
    if (!value.isEmpty())
        builder.append(value, '\n');

    builder.append("AXFocusable: ", element.isFocusable(), '\n');
    builder.append("AXFocused: ", element.isFocused(), '\n');
    builder.append("AXSelectable: ", element.isSelectable(), '\n');
    builder.append("AXSelected: ", element.isSelected(), '\n');
    builder.append("AXMultiSelectable: ", element.isMultiSelectable(), '\n');
    builder.append("AXEnabled: ", element.isEnabled(), '\n');
    builder.append("AXExpanded: ", element.isExpanded(), '\n');
    builder.append("AXRequired: ", element.isRequired(), '\n');
    builder.append("AXChecked: ", element.isChecked(), '\n');

    String url = element.url()->string();
    if (!url.isEmpty())
        builder.append(url, '\n');

    // We append the platform attributes as a single line at the end.
    builder.append("AXPlatformAttributes: ");
    auto attributes = element.platformUIElement()->attributes();
    auto keys = copyToVector(attributes.keys());
    std::sort(keys.begin(), keys.end(), WTF::codePointCompareLessThan);

    bool isFirst = true;
    for (const auto& key : keys) {
        if (key == "id" || key == "toolkit")
            continue;

        if (!isFirst)
            builder.append(", ");
        isFirst = false;
        builder.append(key, ':', attributes.get(key));
    }

    return builder.toString();
}

static String attributesOfElements(Vector<RefPtr<AccessibilityUIElement>>& elements)
{
    StringBuilder builder;
    for (auto& element : elements)
        builder.append(attributesOfElement(*element), "\n------------\n");
    return builder.toString();
}

static Vector<RefPtr<AccessibilityUIElement>> elementsVector(const Vector<RefPtr<WebCore::AccessibilityObjectAtspi>>& wrappers)
{
    Vector<RefPtr<AccessibilityUIElement>> elements;
    elements.reserveInitialCapacity(wrappers.size());
    for (auto& wrapper : wrappers)
        elements.uncheckedAppend(AccessibilityUIElement::create(wrapper.get()));
    return elements;
}

static String attributesOfElements(const Vector<RefPtr<WebCore::AccessibilityObjectAtspi>>& wrappers)
{
    auto elements = elementsVector(wrappers);
    return attributesOfElements(elements);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
{
    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(attributesOfElements(m_element->children())).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
{
    return OpaqueJSString::tryCreate(attributesOfElement(*this)).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringDescriptionOfAttributeValue(JSStringRef attribute)
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

static bool checkElementState(WebCore::AccessibilityObjectAtspi* element, WebCore::Atspi::State state)
{
    return element->state() & (G_GUINT64_CONSTANT(1) << state);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
{
    String attributeName = toWTFString(attribute);
    if (attributeName == "AXSelectedText") {
        if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
            return JSStringCreateWithCharacters(nullptr, 0);

        m_element->updateBackingStore();
        auto text = m_element->text();
        auto offset = m_element->selectedRange();
        return OpaqueJSString::tryCreate(text.substring(offset.x(), offset.y() - offset.x())).leakRef();
    }

    m_element->updateBackingStore();
    auto attributes = m_element->attributes();
    if (attributeName == "AXPlaceholderValue")
        return OpaqueJSString::tryCreate(attributes.get("placeholder-text")).leakRef();
    if (attributeName == "AXInvalid") {
        auto textAttributes = m_element->textAttributes();
        auto value = textAttributes.attributes.get("invalid");
        if (value.isEmpty())
            value = checkElementState(m_element.get(), WebCore::Atspi::State::InvalidEntry) ? "true" : "false";
        return OpaqueJSString::tryCreate(value).leakRef();
    }
    if (attributeName == "AXARIALive")
        return OpaqueJSString::tryCreate(attributes.get("live")).leakRef();
    if (attributeName == "AXARIARelevant")
        return OpaqueJSString::tryCreate(attributes.get("relevant")).leakRef();

    return JSStringCreateWithCharacters(nullptr, 0);
}

double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
{
    String attributeName = toWTFString(attribute);
    m_element->updateBackingStore();
    auto attributes = m_element->attributes();
    if (attributeName == "AXARIASetSize")
        return attributes.get("setsize").toDouble();
    if (attributeName == "AXARIAPosInSet")
        return attributes.get("posinset").toDouble();
    if (attributeName == "AXARIAColumnCount")
        return attributes.get("colcount").toDouble();
    if (attributeName == "AXARIARowCount")
        return attributes.get("rowcount").toDouble();
    if (attributeName == "AXARIAColumnIndex")
        return attributes.get("colindex").toDouble();
    if (attributeName == "AXARIARowIndex")
        return attributes.get("rowindex").toDouble();
    if (attributeName == "AXARIAColumnSpan")
        return attributes.get("colspan").toDouble();
    if (attributeName == "AXARIARowSpan")
        return attributes.get("rowspan").toDouble();

    return 0;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::currentStateValue() const
{
    m_element->updateBackingStore();
    auto value = m_element->attributes().get("current");
    return OpaqueJSString::tryCreate(!value.isNull() ? value : "false").leakRef();
}

JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef attribute) const
{
    return nullptr;
}

static JSValueRef makeJSArray(const Vector<RefPtr<AccessibilityUIElement>>& elements)
{
    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);

    size_t elementCount = elements.size();
    auto valueElements = makeUniqueArray<JSValueRef>(elementCount);
    for (size_t i = 0; i < elementCount; i++)
        valueElements[i] = JSObjectMake(context, elements[i]->wrapperClass(), elements[i].get());

    return JSObjectMakeArray(context, elementCount, valueElements.get(), nullptr);
}

JSValueRef AccessibilityUIElement::rowHeaders() const
{
    if (m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table)) {
        m_element->updateBackingStore();
        return makeJSArray(elementsVector(m_element->rowHeaders()));
    }

    if (m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::TableCell)) {
        m_element->updateBackingStore();
        return makeJSArray(elementsVector(m_element->cellRowHeaders()));
    }

    return makeJSArray({ });
}

JSValueRef AccessibilityUIElement::columnHeaders() const
{
    if (m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table)) {
        m_element->updateBackingStore();
        return makeJSArray(elementsVector(m_element->columnHeaders()));
    }

    if (m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::TableCell)) {
        m_element->updateBackingStore();
        return makeJSArray(elementsVector(m_element->cellColumnHeaders()));
    }

    return makeJSArray({ });
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
{
    return nullptr;
}

bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
{
    String attributeName = toWTFString(attribute);
    m_element->updateBackingStore();
    if (attributeName == "AXElementBusy")
        return checkElementState(m_element.get(), WebCore::Atspi::State::Busy);
    if (attributeName == "AXModal")
        return checkElementState(m_element.get(), WebCore::Atspi::State::Modal);
    if (attributeName == "AXSupportsAutoCompletion")
        return checkElementState(m_element.get(), WebCore::Atspi::State::SupportsAutocompletion);
    if (attributeName == "AXInterfaceTable")
        return m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table);
    if (attributeName == "AXInterfaceTableCell")
        return m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::TableCell);
    if (attributeName == "AXARIAAtomic")
        return m_element->attributes().get("atomic") == "true";

    return false;
}

bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
{
    String attributeName = toWTFString(attribute);
    if (attributeName != "AXValue")
        return false;

    m_element->updateBackingStore();
    if (checkElementState(m_element.get(), WebCore::Atspi::State::ReadOnly))
        return false;

    if (checkElementState(m_element.get(), WebCore::Atspi::State::Editable))
        return true;

    if (checkElementState(m_element.get(), WebCore::Atspi::State::Checkable))
        return true;

    auto attributes = m_element->attributes();
    String isReadOnly = attributes.get("readonly");
    if (!isReadOnly.isEmpty())
        return isReadOnly == "true" ? false : true;

    // If we have a listbox or combobox and the value can be set, the options should be selectable.
    auto elementRole = m_element->role();
    switch (elementRole) {
    case WebCore::Atspi::Role::ComboBox:
    case WebCore::Atspi::Role::ListBox:
        if (auto child = childAtIndex(0)) {
            if (elementRole == WebCore::Atspi::Role::ComboBox) {
                // First child is the menu.
                child = child->childAtIndex(0);
            }

            if (child)
                return checkElementState(child->m_element.get(), WebCore::Atspi::State::Selectable);
        }
        break;
    default:
        break;
    }

    if (m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Value) && checkElementState(m_element.get(), WebCore::Atspi::State::Focusable)) {
        if (m_element->minimumValue() != m_element->maximumValue())
            return true;
    }

    return false;
}

bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
{
    String attributeName = toWTFString(attribute);
    m_element->updateBackingStore();
    auto attributes = m_element->attributes();
    if (attributeName == "AXARIASetSize")
        return attributes.contains("setsize");
    if (attributeName == "AXARIAPosInSet")
        return attributes.contains("posinset");
    if (attributeName == "AXARIALive") {
        auto value = attributes.get("live");
        return !value.isEmpty() && value != "off";
    }
    if (attributeName == "AXARIARelevant")
        return attributes.contains("relevant");
    if (attributeName == "AXARIAAtomic")
        return attributes.contains("atomic");
    if (attributeName == "AXElementBusy")
        return true;

    return false;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

static String xmlRoleValueString(const String& xmlRoles)
{
    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> regionRoles = HashSet<String, ASCIICaseInsensitiveHash>({
        "doc-acknowledgments",
        "doc-afterword",
        "doc-appendix",
        "doc-bibliography",
        "doc-chapter",
        "doc-conclusion",
        "doc-credits",
        "doc-endnotes",
        "doc-epilogue",
        "doc-errata",
        "doc-foreword",
        "doc-glossary",
        "doc-glossref",
        "doc-index",
        "doc-introduction",
        "doc-pagelist",
        "doc-part",
        "doc-preface",
        "doc-prologue",
        "doc-toc",
        "region"
    });

    if (regionRoles->contains(xmlRoles))
        return "AXLandmarkRegion"_s;
    if (equalLettersIgnoringASCIICase(xmlRoles, "banner"))
        return "AXLandmarkBanner"_s;
    if (equalLettersIgnoringASCIICase(xmlRoles, "complementary"))
        return "AXLandmarkComplementary"_s;
    if (equalLettersIgnoringASCIICase(xmlRoles, "contentinfo"))
        return "AXLandmarkContentInfo"_s;
    if (equalLettersIgnoringASCIICase(xmlRoles, "form"))
        return "AXLandmarkForm"_s;
    if (equalLettersIgnoringASCIICase(xmlRoles, "main"))
        return "AXLandmarkMain"_s;
    if (equalLettersIgnoringASCIICase(xmlRoles, "navigation"))
        return "AXLandmarkNavigation"_s;
    if (equalLettersIgnoringASCIICase(xmlRoles, "search"))
        return "AXLandmarkSearch"_s;

    return { };
}

static String roleValueToString(unsigned roleValue)
{
    switch (roleValue) {
    case WebCore::Atspi::Role::Alert:
        return "AXAlert"_s;
    case WebCore::Atspi::Role::Article:
        return "AXArticle"_s;
    case WebCore::Atspi::Role::Audio:
        return "AXAudio"_s;
    case WebCore::Atspi::Role::BlockQuote:
        return "AXBlockquote"_s;
    case WebCore::Atspi::Role::Canvas:
        return "AXCanvas"_s;
    case WebCore::Atspi::Role::Caption:
        return "AXCaption"_s;
    case WebCore::Atspi::Role::CheckBox:
        return "AXCheckBox"_s;
    case WebCore::Atspi::Role::CheckMenuItem:
        return "AXCheckMenuItem"_s;
    case WebCore::Atspi::Role::ColorChooser:
        return "AXColorWell"_s;
    case WebCore::Atspi::Role::ColumnHeader:
    case WebCore::Atspi::Role::TableColumnHeader:
        return "AXColumnHeader"_s;
    case WebCore::Atspi::Role::ComboBox:
        return "AXComboBox"_s;
    case WebCore::Atspi::Role::Comment:
        return "AXComment"_s;
    case WebCore::Atspi::Role::ContentDeletion:
        return "AXDeletion"_s;
    case WebCore::Atspi::Role::ContentInsertion:
        return "AXInsertion"_s;
    case WebCore::Atspi::Role::Definition:
        return "AXDefinition"_s;
    case WebCore::Atspi::Role::DescriptionList:
        return "AXDescriptionList"_s;
    case WebCore::Atspi::Role::DescriptionTerm:
        return "AXDescriptionTerm"_s;
    case WebCore::Atspi::Role::DescriptionValue:
        return "AXDescriptionValue"_s;
    case WebCore::Atspi::Role::Dialog:
        return "AXDialog"_s;
    case WebCore::Atspi::Role::DocumentFrame:
        return "AXDocument"_s;
    case WebCore::Atspi::Role::DocumentWeb:
        return "AXWebArea"_s;
    case WebCore::Atspi::Role::Embedded:
        return "AXEmbedded"_s;
    case WebCore::Atspi::Role::Entry:
        return "AXTextField"_s;
    case WebCore::Atspi::Role::Footer:
        return "AXFooter"_s;
    case WebCore::Atspi::Role::Footnote:
        return "AXFootnote"_s;
    case WebCore::Atspi::Role::Form:
        return "AXForm"_s;
    case WebCore::Atspi::Role::Grouping:
    case WebCore::Atspi::Role::Panel:
        return "AXGroup"_s;
    case WebCore::Atspi::Role::Heading:
        return "AXHeading"_s;
    case WebCore::Atspi::Role::Image:
        return "AXImage"_s;
    case WebCore::Atspi::Role::ImageMap:
        return "AXImageMap"_s;
    case WebCore::Atspi::Role::InvalidRole:
        return "AXInvalid"_s;
    case WebCore::Atspi::Role::Label:
        return "AXLabel"_s;
    case WebCore::Atspi::Role::LevelBar:
        return "AXLevelIndicator"_s;
    case WebCore::Atspi::Role::Link:
        return "AXLink"_s;
    case WebCore::Atspi::Role::ListBox:
        return "AXListBox"_s;
    case WebCore::Atspi::Role::List:
        return "AXList"_s;
    case WebCore::Atspi::Role::ListItem:
        return "AXListItem"_s;
    case WebCore::Atspi::Role::Log:
        return "AXLog"_s;
    case WebCore::Atspi::Role::Marquee:
        return "AXMarquee"_s;
    case WebCore::Atspi::Role::Math:
        return "AXMath"_s;
    case WebCore::Atspi::Role::MathFraction:
        return "AXMathFraction"_s;
    case WebCore::Atspi::Role::MathRoot:
        return "AXMathRoot"_s;
    case WebCore::Atspi::Role::Menu:
        return "AXMenu"_s;
    case WebCore::Atspi::Role::MenuBar:
        return "AXMenuBar"_s;
    case WebCore::Atspi::Role::MenuItem:
        return "AXMenuItem"_s;
    case WebCore::Atspi::Role::Notification:
        return "AXNotification"_s;
    case WebCore::Atspi::Role::PageTab:
        return "AXTab"_s;
    case WebCore::Atspi::Role::PageTabList:
        return "AXTabGroup"_s;
    case WebCore::Atspi::Role::Paragraph:
        return "AXParagraph"_s;
    case WebCore::Atspi::Role::PasswordText:
        return "AXPasswordField"_s;
    case WebCore::Atspi::Role::ProgressBar:
        return "AXProgressIndicator"_s;
    case WebCore::Atspi::Role::PushButton:
        return "AXButton"_s;
    case WebCore::Atspi::Role::RadioButton:
        return "AXRadioButton"_s;
    case WebCore::Atspi::Role::RadioMenuItem:
        return "AXRadioMenuItem"_s;
    case WebCore::Atspi::Role::RowHeader:
    case WebCore::Atspi::Role::TableRowHeader:
        return "AXRowHeader"_s;
    case WebCore::Atspi::Role::Ruler:
        return "AXRuler"_s;
    case WebCore::Atspi::Role::ScrollBar:
        return "AXScrollBar"_s;
    case WebCore::Atspi::Role::ScrollPane:
        return "AXScrollArea";
    case WebCore::Atspi::Role::Section:
        return "AXSection"_s;
    case WebCore::Atspi::Role::Separator:
        return "AXSeparator"_s;
    case WebCore::Atspi::Role::Slider:
        return "AXSlider"_s;
    case WebCore::Atspi::Role::SpinButton:
        return "AXSpinButton"_s;
    case WebCore::Atspi::Role::Static:
        return "AXStatic"_s;
    case WebCore::Atspi::Role::StatusBar:
        return "AXStatusBar"_s;
    case WebCore::Atspi::Role::Subscript:
        return "AXSubscript"_s;
    case WebCore::Atspi::Role::Superscript:
        return "AXSuperscript"_s;
    case WebCore::Atspi::Role::Table:
        return "AXTable"_s;
    case WebCore::Atspi::Role::TableCell:
        return "AXCell"_s;
    case WebCore::Atspi::Role::TableRow:
        return "AXRow"_s;
    case WebCore::Atspi::Role::Timer:
        return "AXTimer"_s;
    case WebCore::Atspi::Role::ToggleButton:
        return "AXToggleButton"_s;
    case WebCore::Atspi::Role::ToolBar:
        return "AXToolbar"_s;
    case WebCore::Atspi::Role::ToolTip:
        return "AXUserInterfaceTooltip"_s;
    case WebCore::Atspi::Role::Tree:
        return "AXTree"_s;
    case WebCore::Atspi::Role::TreeTable:
        return "AXTreeGrid"_s;
    case WebCore::Atspi::Role::TreeItem:
        return "AXTreeItem"_s;
    case WebCore::Atspi::Role::Unknown:
        return "AXUnknown"_s;
    case WebCore::Atspi::Role::Video:
        return "AXVideo"_s;
    case WebCore::Atspi::Role::Window:
        return "AXWindow"_s;
    default:
        break;
    }

    return { };
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
{
    m_element->updateBackingStore();
    auto roleValue = m_element->role();
    auto roleValueString = roleValue == WebCore::Atspi::Role::Landmark ? xmlRoleValueString(m_element->attributes().get("xml-roles")) : roleValueToString(roleValue);
    if (roleValueString.isEmpty())
        return JSStringCreateWithCharacters(nullptr, 0);

    return OpaqueJSString::tryCreate(makeString("AXRole: ", roleValueString)).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
{
    m_element->updateBackingStore();
    auto roleDescription = m_element->attributes().get("roledescription");
    return OpaqueJSString::tryCreate(makeString("AXRoleDescription: ", roleDescription)).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::computedRoleString()
{
    m_element->updateBackingStore();
    auto computedRole = m_element->attributes().get("computed-role");
    if (computedRole.isEmpty())
        return JSStringCreateWithCharacters(nullptr, 0);

    return OpaqueJSString::tryCreate(computedRole).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
{
    m_element->updateBackingStore();
    auto titleValue = makeString("AXTitle: ", String::fromUTF8(m_element->name()));
    return OpaqueJSString::tryCreate(titleValue).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
{
    m_element->updateBackingStore();
    auto descriptionValue = makeString("AXDescription: ", String::fromUTF8(m_element->description()));
    return OpaqueJSString::tryCreate(descriptionValue).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
{
    m_element->updateBackingStore();
    const char* orientation = nullptr;
    if (checkElementState(m_element.get(), WebCore::Atspi::State::Horizontal))
        orientation = "AXHorizontalOrientation";
    else if (checkElementState(m_element.get(), WebCore::Atspi::State::Vertical))
        orientation = "AXVerticalOrientation";
    else
        orientation = "AXUnknownOrientation";

    auto orientationValue = makeString("AXOrientation: ", orientation);
    return OpaqueJSString::tryCreate(orientationValue).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    auto value = makeString("AXValue: ", m_element->text().replace("\n", "<\\n>").replace(objectReplacementCharacter, "<obj>"));
    return OpaqueJSString::tryCreate(value).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
{
    m_element->updateBackingStore();
    auto locale = m_element->locale();
    if (locale.isEmpty())
        return JSStringCreateWithCharacters(nullptr, 0);

    return OpaqueJSString::tryCreate(makeString("AXLanguage: ", locale)).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
{
    m_element->updateBackingStore();
    auto relationMap = m_element->relationMap();
    auto targets = relationMap.get(WebCore::Atspi::Relation::DescribedBy);
    if (targets.isEmpty())
        return JSStringCreateWithCharacters(nullptr, 0);

    StringBuilder builder;
    builder.append("AXHelp: ");

    bool isFirst = true;
    for (const auto& target : targets) {
        if (!isFirst)
            builder.append(' ');
        isFirst = false;
        target->updateBackingStore();
        builder.append(target->text());
    }

    return OpaqueJSString::tryCreate(builder.toString()).leakRef();
}

double AccessibilityUIElement::x()
{
    m_element->updateBackingStore();
    return m_element->elementRect(WebCore::Atspi::CoordinateType::ScreenCoordinates).x();
}

double AccessibilityUIElement::y()
{
    m_element->updateBackingStore();
    return m_element->elementRect(WebCore::Atspi::CoordinateType::ScreenCoordinates).y();
}

double AccessibilityUIElement::width()
{
    m_element->updateBackingStore();
    return m_element->elementRect(WebCore::Atspi::CoordinateType::ScreenCoordinates).width();
}

double AccessibilityUIElement::height()
{
    m_element->updateBackingStore();
    return m_element->elementRect(WebCore::Atspi::CoordinateType::ScreenCoordinates).height();
}

double AccessibilityUIElement::clickPointX()
{
    m_element->updateBackingStore();
    auto rect = m_element->elementRect(WebCore::Atspi::CoordinateType::WindowCoordinates);
    return rect.center().x();
}

double AccessibilityUIElement::clickPointY()
{
    m_element->updateBackingStore();
    auto rect = m_element->elementRect(WebCore::Atspi::CoordinateType::WindowCoordinates);
    return rect.center().y();
}

double AccessibilityUIElement::intValue() const
{
    m_element->updateBackingStore();
    if (m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Value))
        return m_element->currentValue();

    // Consider headings as an special case when returning the int value.
    if (m_element->role() == WebCore::Atspi::Role::Heading)
        return m_element->attributes().get("level").toDouble();

    return 0;
}

double AccessibilityUIElement::minValue()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Value))
        return 0;

    m_element->updateBackingStore();
    return m_element->minimumValue();
}

double AccessibilityUIElement::maxValue()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Value))
        return 0;

    m_element->updateBackingStore();
    return m_element->maximumValue();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
{
    m_element->updateBackingStore();
    auto attributes = m_element->attributes();
    auto value = makeString("AXValueDescription: ", attributes.get("valuetext"));
    return OpaqueJSString::tryCreate(value).leakRef();
}

int AccessibilityUIElement::insertionPointLineNumber()
{
    return -1;
}

bool AccessibilityUIElement::isPressActionSupported()
{
    m_element->updateBackingStore();
    auto name = m_element->actionName();
    return name == "press" || name == "jump";
}

bool AccessibilityUIElement::isIncrementActionSupported()
{
    return false;
}

bool AccessibilityUIElement::isDecrementActionSupported()
{
    return false;
}

bool AccessibilityUIElement::isEnabled()
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Enabled);
}

bool AccessibilityUIElement::isRequired() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Required);
}

bool AccessibilityUIElement::isFocused() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Focused);
}

bool AccessibilityUIElement::isSelected() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Selected);
}

bool AccessibilityUIElement::isSelectedOptionActive() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Active);
}

bool AccessibilityUIElement::isExpanded() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Expanded);
}

bool AccessibilityUIElement::isChecked() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Checked);
}

bool AccessibilityUIElement::isIndeterminate() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Indeterminate);
}

int AccessibilityUIElement::hierarchicalLevel() const
{
    m_element->updateBackingStore();
    auto level = m_element->attributes().get("level");
    if (level.isEmpty())
        return 0;

    return parseIntegerAllowingTrailingJunk<int>(level).value_or(0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::speakAs()
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

bool AccessibilityUIElement::ariaIsGrabbed() const
{
    m_element->updateBackingStore();
    return m_element->attributes().get("grabbed") == "true";
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
{
    m_element->updateBackingStore();
    auto dropEffects = m_element->attributes().get("dropeffect");
    if (dropEffects.isEmpty())
        return JSStringCreateWithCharacters(nullptr, 0);
    return OpaqueJSString::tryCreate(dropEffects).leakRef();
}

int AccessibilityUIElement::lineForIndex(int index)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return -1;

    m_element->updateBackingStore();
    auto text = m_element->text();
    if (index < 0 || index > static_cast<int>(text.length()))
        return -1;

    int lineNumber = 0;
    for (int i = 0; i < index; ++i) {
        if (text[i] == '\n')
            lineNumber++;
    }

    return lineNumber;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    WebCore::IntPoint offset;
    for (int i = 0; i <= line; ++i)
        offset = m_element->boundaryOffset(offset.y(), WebCore::AccessibilityObjectAtspi::TextGranularity::LineStart);

    auto range = makeString('{', offset.x(), ", ", offset.y() - offset.x(), '}');
    return OpaqueJSString::tryCreate(range).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    auto rect = m_element->boundsForRange(location, length, WebCore::Atspi::CoordinateType::WindowCoordinates);
    auto bounds = makeString('{', rect.x(), ", ", rect.y(), ", ", rect.width(), ", ", rect.height(), '}');
    return OpaqueJSString::tryCreate(bounds).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(m_element->text().substring(location, length)).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return JSStringCreateWithCharacters(nullptr, 0);

    StringBuilder builder;

    auto buildAttributes = [&](const WebCore::AccessibilityObjectAtspi::TextAttributes& attributes) {
        for (const auto& it : attributes.attributes) {
            builder.append("\n\t\t");
            builder.append(it.key, ':', it.value);
        }
    };

    m_element->updateBackingStore();
    builder.append("\n\tDefault text attributes:");
    buildAttributes(m_element->textAttributes());

    auto text = m_element->text();
    int endOffset = 0;
    for (unsigned i = location; i < location + length; i = endOffset) {
        auto attributes = m_element->textAttributes(i);
        auto rangeStart = std::max<int>(location, attributes.startOffset);
        auto rangeEnd = std::min<int>(location + length, attributes.endOffset);
        builder.append("\n\tRange attributes for '", text.substring(rangeStart, rangeEnd - rangeStart).replace("\n", "<\\n>").replace(objectReplacementCharacter, "<obj>"), "':");
        buildAttributes(attributes);
        endOffset = attributes.endOffset;
    }

    return OpaqueJSString::tryCreate(builder.toString()).leakRef();
}

bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
{
    return false;
}

unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
{
    return 0;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::selectTextWithCriteria(JSContextRef context, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity)
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(attributesOfElements(m_element->columnHeaders())).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(attributesOfElements(m_element->rowHeaders())).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(attributesOfElements(m_element->rows())).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(attributesOfElements(m_element->cells())).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

int AccessibilityUIElement::rowCount()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return 0;

    m_element->updateBackingStore();
    return m_element->rowCount();
}

int AccessibilityUIElement::columnCount()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return 0;

    m_element->updateBackingStore();
    return m_element->columnCount();
}

int AccessibilityUIElement::indexInTable()
{
    return -1;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::TableCell))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    auto position = m_element->cellPosition().first;
    auto span = m_element->rowSpan();
    if (!position || !span)
        return JSStringCreateWithCharacters(nullptr, 0);

    return OpaqueJSString::tryCreate(makeString('{', *position, ", ", span, '}')).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::TableCell))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    auto position = m_element->cellPosition().second;
    auto span = m_element->columnSpan();
    if (!position || !span)
        return JSStringCreateWithCharacters(nullptr, 0);

    return OpaqueJSString::tryCreate(makeString('{', *position, ", ", span, '}')).leakRef();
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Table))
        return nullptr;

    m_element->updateBackingStore();
    if (auto* cell = m_element->cell(row, column))
        return AccessibilityUIElement::create(cell);
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
{
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    auto offset = m_element->selectedRange();
    auto range = makeString('{', offset.x(), ", ", offset.y() - offset.x(), '}');
    return OpaqueJSString::tryCreate(range).leakRef();
}

bool AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return false;

    m_element->updateBackingStore();
    auto textLength = m_element->text().length();
    m_element->setSelectedRange(std::min(location, textLength), std::min(length, textLength));
    return true;
}

void AccessibilityUIElement::increment()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Value))
        return;

    m_element->updateBackingStore();
    m_element->setCurrentValue(intValue() + m_element->minimumIncrement());
}

void AccessibilityUIElement::decrement()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Value))
        return;

    m_element->updateBackingStore();
    m_element->setCurrentValue(intValue() - m_element->minimumIncrement());
}

void AccessibilityUIElement::showMenu()
{
}

void AccessibilityUIElement::press()
{
    m_element->updateBackingStore();
    m_element->doAction();
}

void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
{
}

void AccessibilityUIElement::setSelectedChildAtIndex(unsigned index) const
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Selection))
        return;

    m_element->updateBackingStore();
    m_element->setChildSelected(index, true);
}

void AccessibilityUIElement::removeSelectionAtIndex(unsigned index) const
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Selection))
        return;

    m_element->updateBackingStore();
    m_element->setChildSelected(index, false);
}

void AccessibilityUIElement::clearSelectedChildren() const
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Selection))
        return;

    m_element->updateBackingStore();
    m_element->clearSelection();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Document))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(m_element->documentAttribute("Encoding")).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Document))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    return OpaqueJSString::tryCreate(m_element->documentAttribute("URI")).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Hyperlink))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    auto axURL = m_element->url();
    if (axURL.isNull())
        return JSStringCreateWithUTF8CString("AXURL: (null)");

    auto stringURL = axURL.string();
    if (axURL.isLocalFile()) {
        // Do not expose absolute paths.
        auto index = stringURL.find("LayoutTests");
        if (index != notFound)
            stringURL = stringURL.substring(index);
    }
    return OpaqueJSString::tryCreate(makeString("AXURL: ", stringURL)).leakRef();
}

bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
{
    if (!functionCallback)
        return false;

    if (m_notificationHandler)
        return false;

    m_notificationHandler = makeUnique<AccessibilityNotificationHandler>(functionCallback, m_element.get());
    return true;
}

bool AccessibilityUIElement::removeNotificationListener()
{
    ASSERT(m_notificationHandler);
    m_notificationHandler = nullptr;
    return true;
}

bool AccessibilityUIElement::isFocusable() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Focusable);
}

bool AccessibilityUIElement::isSelectable() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Selectable);
}

bool AccessibilityUIElement::isMultiSelectable() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Multiselectable);
}

bool AccessibilityUIElement::isVisible() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Visible);
}

bool AccessibilityUIElement::isOffScreen() const
{
    m_element->updateBackingStore();
    return !checkElementState(m_element.get(), WebCore::Atspi::State::Showing);
}

bool AccessibilityUIElement::isCollapsed() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::Collapsed);
}

bool AccessibilityUIElement::isIgnored() const
{
    return false;
}

bool AccessibilityUIElement::isSingleLine() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::SingleLine);
}

bool AccessibilityUIElement::isMultiLine() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::MultiLine);
}

bool AccessibilityUIElement::hasPopup() const
{
    m_element->updateBackingStore();
    return checkElementState(m_element.get(), WebCore::Atspi::State::HasPopup);
}

void AccessibilityUIElement::takeFocus()
{
}

void AccessibilityUIElement::takeSelection()
{
}

void AccessibilityUIElement::addSelection()
{
}

void AccessibilityUIElement::removeSelection()
{
}

// Text markers
RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
{
    return nullptr;
}

int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
{
    return 0;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange)
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::rectsForTextMarkerRange(AccessibilityTextMarkerRange* markerRange, JSStringRef searchText)
{
    return JSStringCreateWithCharacters(nullptr, 0);
}

RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int x, int y, int width, int height)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int x, int y, int width, int height)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
{
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRange(AccessibilityTextMarkerRange*)
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRangeWithOptions(AccessibilityTextMarkerRange*, bool)
{
    return nullptr;
}

bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef attribute, AccessibilityTextMarkerRange* range)
{
    return false;
}

int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker)
{
    return -1;
}

bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker)
{
    return false;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
{
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
{
    return nullptr;
}

bool AccessibilityUIElement::setSelectedTextMarkerRange(AccessibilityTextMarkerRange*)
{
    return false;
}

void AccessibilityUIElement::scrollToMakeVisible()
{
    m_element->updateBackingStore();
    m_element->scrollToMakeVisible(WebCore::Atspi::ScrollType::Anywhere);
}

void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
{
    m_element->updateBackingStore();
    m_element->scrollToPoint({ x, y }, WebCore::Atspi::CoordinateType::WindowCoordinates);
}

void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
{
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const
{
    return nullptr;
}

static String stringAtOffset(WebCore::AccessibilityObjectAtspi* element, int offset, WebCore::AccessibilityObjectAtspi::TextGranularity granularity)
{
    if (!element || !element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return { };

    element->updateBackingStore();
    auto text = element->text();
    if (offset < 0 || offset > static_cast<int>(text.length()))
        return { };

    auto bounds = element->boundaryOffset(offset, granularity);
    unsigned startOffset = std::max<int>(bounds.x(), 0);
    unsigned endOffset = std::min<int>(bounds.y(), text.length());
    return makeString(text.substring(startOffset, endOffset - startOffset), ", ", startOffset, ", ", endOffset);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::characterAtOffset(int offset)
{
    if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Text))
        return JSStringCreateWithCharacters(nullptr, 0);

    m_element->updateBackingStore();
    auto text = m_element->text();
    if (offset < 0 || offset > static_cast<int>(text.length()))
        return JSStringCreateWithCharacters(nullptr, 0);

    auto string = makeString(text.substring(offset, 1), ", ", offset, ", ", offset + 1);
    return OpaqueJSString::tryCreate(string).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::wordAtOffset(int offset)
{
    return OpaqueJSString::tryCreate(stringAtOffset(m_element.get(), offset, WebCore::AccessibilityObjectAtspi::TextGranularity::WordStart)).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::lineAtOffset(int offset)
{
    return OpaqueJSString::tryCreate(stringAtOffset(m_element.get(), offset, WebCore::AccessibilityObjectAtspi::TextGranularity::LineStart)).leakRef();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::sentenceAtOffset(int offset)
{
    return OpaqueJSString::tryCreate(stringAtOffset(m_element.get(), offset, WebCore::AccessibilityObjectAtspi::TextGranularity::SentenceStart)).leakRef();
}

bool AccessibilityUIElement::replaceTextInRange(JSStringRef, int, int)
{
    return false;
}

bool AccessibilityUIElement::insertText(JSStringRef)
{
    return false;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::popupValue() const
{
    return nullptr;
}

} // namespace WTR

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