/*
 * 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 "AXObjectCache.h"
#include "AccessibilityAtspiEnums.h"
#include "AccessibilityObject.h"
#include "AccessibilityObjectInterface.h"
#include "AccessibilityRootAtspi.h"
#include "Editing.h"
#include "PlatformScreen.h"
#include "RenderLayer.h"
#include "SurrogatePairAwareTextIterator.h"
#include "TextIterator.h"
#include "VisibleUnits.h"
#include <gio/gio.h>

namespace WebCore {

AccessibilityObjectAtspi::TextGranularity AccessibilityObjectAtspi::atspiBoundaryToTextGranularity(uint32_t boundaryType)
{
    switch (boundaryType) {
    case Atspi::TextBoundaryType::CharBoundary:
        return TextGranularity::Character;
    case Atspi::TextBoundaryType::WordStartBoundary:
        return TextGranularity::WordStart;
    case Atspi::TextBoundaryType::WordEndBoundary:
        return TextGranularity::WordEnd;
    case Atspi::TextBoundaryType::SentenceStartBoundary:
        return TextGranularity::SentenceStart;
    case Atspi::TextBoundaryType::SentenceEndBoundary:
        return TextGranularity::SentenceEnd;
    case Atspi::TextBoundaryType::LineStartBoundary:
        return TextGranularity::LineStart;
    case Atspi::TextBoundaryType::LineEndBoundary:
        return TextGranularity::LineEnd;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

AccessibilityObjectAtspi::TextGranularity AccessibilityObjectAtspi::atspiGranularityToTextGranularity(uint32_t boundaryType)
{
    switch (boundaryType) {
    case Atspi::TextGranularityType::CharGranularity:
        return TextGranularity::Character;
    case Atspi::TextGranularityType::WordGranularity:
        return TextGranularity::WordStart;
    case Atspi::TextGranularityType::SentenceGranularity:
        return TextGranularity::SentenceStart;
    case Atspi::TextGranularityType::LineGranularity:
        return TextGranularity::LineStart;
    case Atspi::TextGranularityType::ParagraphGranularity:
        return TextGranularity::Paragraph;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

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

        if (!g_strcmp0(methodName, "GetStringAtOffset")) {
            int offset;
            uint32_t granularityType;
            g_variant_get(parameters, "(iu)", &offset, &granularityType);
            int start = 0, end = 0;
            auto text = atspiObject->textAtOffset(offset, atspiGranularityToTextGranularity(granularityType), start, end);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(sii)", text.isNull() ? "" : text.data(), start, end));
        } else if (!g_strcmp0(methodName, "GetText")) {
            int start, end;
            g_variant_get(parameters, "(ii)", &start, &end);
            auto text = atspiObject->text(start, end);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", text.isNull() ? "" : text.data()));
        } else if (!g_strcmp0(methodName, "SetCaretOffset")) {
            int offset;
            g_variant_get(parameters, "(i)", &offset);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", atspiObject->selectRange(offset, offset)));
        } else if (!g_strcmp0(methodName, "GetTextBeforeOffset")) {
            g_dbus_method_invocation_return_error_literal(invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
        } else if (!g_strcmp0(methodName, "GetTextAtOffset")) {
            int offset;
            uint32_t boundaryType;
            g_variant_get(parameters, "(iu)", &offset, &boundaryType);
            int start = 0, end = 0;
            auto text = atspiObject->textAtOffset(offset, atspiBoundaryToTextGranularity(boundaryType), start, end);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(sii)", text.isNull() ? "" : text.data(), start, end));
        } else if (!g_strcmp0(methodName, "GetTextAfterOffset"))
            g_dbus_method_invocation_return_error_literal(invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
        else if (!g_strcmp0(methodName, "GetCharacterAtOffset")) {
            int offset;
            g_variant_get(parameters, "(i)", &offset);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", atspiObject->characterAtOffset(offset)));
        } else if (!g_strcmp0(methodName, "GetAttributeValue")) {
            int offset;
            const char* name;
            g_variant_get(parameters, "(i&s)", &offset, &name);
            auto attributes = atspiObject->textAttributesWithUTF8Offset(offset);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", attributes.attributes.get(String::fromUTF8(name)).utf8().data()));
        } else if (!g_strcmp0(methodName, "GetAttributes")) {
            int offset;
            g_variant_get(parameters, "(i)", &offset);
            auto attributes = atspiObject->textAttributesWithUTF8Offset(offset);
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("a{ss}"));
            for (const auto& it : attributes.attributes)
                g_variant_builder_add(&builder, "{ss}", it.key.utf8().data(), it.value.utf8().data());
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(a{ss}ii)", &builder, attributes.startOffset, attributes.endOffset));
        } else if (!g_strcmp0(methodName, "GetAttributeRun")) {
            int offset;
            gboolean includeDefaults;
            g_variant_get(parameters, "(ib)", &offset, &includeDefaults);
            auto attributes = atspiObject->textAttributesWithUTF8Offset(offset, includeDefaults);
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("a{ss}"));
            for (const auto& it : attributes.attributes)
                g_variant_builder_add(&builder, "{ss}", it.key.utf8().data(), it.value.utf8().data());
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(a{ss}ii)", &builder, attributes.startOffset, attributes.endOffset));
        } else if (!g_strcmp0(methodName, "GetDefaultAttributes") || !g_strcmp0(methodName, "GetDefaultAttributeSet")) {
            auto attributes = atspiObject->textAttributesWithUTF8Offset();
            GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("a{ss}"));
            for (const auto& it : attributes.attributes)
                g_variant_builder_add(&builder, "{ss}", it.key.utf8().data(), it.value.utf8().data());
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(a{ss})", &builder));
        } else if (!g_strcmp0(methodName, "GetCharacterExtents")) {
            int offset;
            uint32_t coordinateType;
            g_variant_get(parameters, "(iu)", &offset, &coordinateType);
            auto extents = atspiObject->textExtents(offset, offset + 1, coordinateType);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(iiii)", extents.x(), extents.y(), extents.width(), extents.height()));
        } else if (!g_strcmp0(methodName, "GetRangeExtents")) {
            int start, end;
            uint32_t coordinateType;
            g_variant_get(parameters, "(iiu)", &start, &end, &coordinateType);
            auto extents = atspiObject->textExtents(start, end, coordinateType);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(iiii)", extents.x(), extents.y(), extents.width(), extents.height()));
        } else if (!g_strcmp0(methodName, "GetOffsetAtPoint")) {
            int x, y;
            uint32_t coordinateType;
            g_variant_get(parameters, "(iiu)", &x, &y, &coordinateType);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", atspiObject->offsetAtPoint(IntPoint(x, y), coordinateType)));
        } else if (!g_strcmp0(methodName, "GetNSelections")) {
            int start, end;
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", atspiObject->selectionBounds(start, end) && start != end ? 1 : 0));
        } else if (!g_strcmp0(methodName, "GetSelection")) {
            int selectionNumber;
            g_variant_get(parameters, "(i)", &selectionNumber);
            if (selectionNumber)
                g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Not a valid selection: %d", selectionNumber);
            else {
                int start = 0, end = 0;
                if (atspiObject->selectionBounds(start, end) && start == end)
                    start = end = 0;
                g_dbus_method_invocation_return_value(invocation, g_variant_new("(ii)", start, end));
            }
        } else if (!g_strcmp0(methodName, "AddSelection")) {
            int start, end;
            g_variant_get(parameters, "(ii)", &start, &end);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", atspiObject->selectRange(start, end)));
        } else if (!g_strcmp0(methodName, "SetSelection")) {
            int start, end, selectionNumber;
            g_variant_get(parameters, "(iii)", &selectionNumber, &start, &end);
            if (selectionNumber)
                g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Not a valid selection: %d", selectionNumber);
            else
                g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", atspiObject->selectRange(start, end)));
        } else if (!g_strcmp0(methodName, "RemoveSelection")) {
            int selectionNumber;
            int caretOffset = -1;
            if (!selectionNumber) {
                int start, end;
                if (atspiObject->selectionBounds(start, end))
                    caretOffset = end;
            }
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", caretOffset != -1 ? atspiObject->selectRange(caretOffset, caretOffset) : FALSE));
        } else if (!g_strcmp0(methodName, "ScrollSubstringTo")) {
            int start, end;
            uint32_t scrollType;
            g_variant_get(parameters, "(iiu)", &start, &end, &scrollType);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", atspiObject->scrollToMakeVisible(start, end, scrollType)));
        } else if (!g_strcmp0(methodName, "ScrollSubstringToPoint")) {
            int start, end, x, y;
            uint32_t coordinateType;
            g_variant_get(parameters, "(iiuii)", &start, &end, &coordinateType, &x, &y);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", atspiObject->scrollToPoint(start, end, coordinateType, x, y)));
        } else if (!g_strcmp0(methodName, "GetBoundedRanges") || !g_strcmp0(methodName, "ScrollSubstringToPoint"))
            g_dbus_method_invocation_return_error_literal(invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
    },
    // get_property
    [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar* propertyName, GError** error, gpointer userData) -> GVariant* {
        RELEASE_ASSERT(!isMainThread());
        auto atspiObject = Ref { *static_cast<AccessibilityObjectAtspi*>(userData) };
        atspiObject->updateBackingStore();

        if (!g_strcmp0(propertyName, "CharacterCount"))
            return g_variant_new_int32(g_utf8_strlen(atspiObject->text().utf8().data(), -1));
        if (!g_strcmp0(propertyName, "CaretOffset")) {
            int start = 0, end = 0;
            return g_variant_new_int32(atspiObject->selectionBounds(start, end) ? end : -1);
        }

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

static Vector<unsigned, 128> offsetMapping(const String& text)
{
    if (text.is8Bit())
        return { };

    Vector<unsigned, 128> offsets;
    SurrogatePairAwareTextIterator iterator(text.characters16(), 0, text.length(), text.length());
    UChar32 character;
    unsigned clusterLength = 0;
    unsigned i;
    for (i = 0; iterator.consume(character, clusterLength); iterator.advance(clusterLength), ++i) {
        for (unsigned j = 0; j < clusterLength; ++j)
            offsets.append(i);
    }
    offsets.append(i++);
    return offsets;
}

static inline unsigned UTF16OffsetToUTF8(const Vector<unsigned, 128>& mapping, unsigned offset)
{
    return mapping.isEmpty() ? offset : mapping[offset];
}

static inline unsigned UTF8OffsetToUTF16(const Vector<unsigned, 128>& mapping, unsigned offset)
{
    if (mapping.isEmpty())
        return offset;

    for (unsigned i = offset; i < mapping.size(); ++i) {
        if (mapping[i] == offset)
            return i;
    }
    return mapping.size();
}

String AccessibilityObjectAtspi::text() const
{
    AXCoreObject* axObject = isMainThread() ? m_coreObject : m_axObject;
    if (!axObject)
        return { };

#if ENABLE(INPUT_TYPE_COLOR)
    if (axObject->roleValue() == AccessibilityRole::ColorWell) {
        auto color = convertColor<SRGBA<float>>(axObject->colorValue());
        GUniquePtr<char> colorString(g_strdup_printf("rgb %7.5f %7.5f %7.5f 1", color.red, color.green, color.blue));
        return String::fromUTF8(colorString.get());
    }
#endif

    if (axObject->isTextControl())
        return axObject->doAXStringForRange({ 0, String::MaxLength });

    auto value = axObject->stringValue();
    if (!value.isNull())
        return value;

    if (axObject == m_coreObject)
        return m_coreObject->textUnderElement(AccessibilityTextUnderElementMode(AccessibilityTextUnderElementMode::TextUnderElementModeIncludeAllChildren));

    return Accessibility::retrieveValueFromMainThread<String>([this]() -> String {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject)
            return { };
        return m_coreObject->textUnderElement(AccessibilityTextUnderElementMode(AccessibilityTextUnderElementMode::TextUnderElementModeIncludeAllChildren)).isolatedCopy();
    });
}

unsigned AccessibilityObject::getLengthForTextRange() const
{
    RELEASE_ASSERT(isMainThread());
    // FIXME: this should probably be in sync with AccessibilityObjectAtspi::text().
    unsigned textLength = text().length();
    if (textLength)
        return textLength;

    Node* node = this->node();
    RenderObject* renderer = node ? node->renderer() : nullptr;
    if (is<RenderText>(renderer))
        textLength = downcast<RenderText>(*renderer).text().length();

    if (!textLength && allowsTextRanges())
        textLength = textUnderElement(AccessibilityTextUnderElementMode(AccessibilityTextUnderElementMode::TextUnderElementModeIncludeAllChildren)).length();

    return textLength;
}

bool AccessibilityObject::allowsTextRanges() const
{
    return true;
}

CString AccessibilityObjectAtspi::text(int startOffset, int endOffset) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return { };

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    if (endOffset == -1)
        endOffset = length;

    if (startOffset < 0 || endOffset < 0)
        return { };

    if (endOffset <= startOffset)
        return { };

    if (!startOffset && endOffset == length)
        return utf8Text;

    GUniquePtr<char> substring(g_utf8_substring(utf8Text.data(), startOffset, endOffset));
    return substring.get();
}

void AccessibilityObjectAtspi::textInserted(const String& insertedText, const VisiblePosition& position)
{
    RELEASE_ASSERT(isMainThread());
    if (!m_isRegistered.load())
        return;

    if (!m_interfaces.contains(Interface::Text))
        return;

    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    auto utf16Offset = m_coreObject->indexForVisiblePosition(position);
    auto mapping = offsetMapping(utf16Text);
    auto offset = UTF16OffsetToUTF8(mapping, utf16Offset);
    auto utf8InsertedText = insertedText.utf8();
    auto insertedTextLength = g_utf8_strlen(utf8InsertedText.data(), -1);
    root()->atspi().textChanged(*this, "insert", WTFMove(utf8InsertedText), offset - insertedTextLength, insertedTextLength);
}

void AccessibilityObjectAtspi::textDeleted(const String& deletedText, const VisiblePosition& position)
{
    RELEASE_ASSERT(isMainThread());
    if (!m_isRegistered.load())
        return;

    if (!m_interfaces.contains(Interface::Text))
        return;

    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    auto utf16Offset = m_coreObject->indexForVisiblePosition(position);
    auto mapping = offsetMapping(utf16Text);
    auto offset = UTF16OffsetToUTF8(mapping, utf16Offset);
    auto utf8DeletedText = deletedText.utf8();
    auto deletedTextLength = g_utf8_strlen(utf8DeletedText.data(), -1);
    root()->atspi().textChanged(*this, "delete", WTFMove(utf8DeletedText), offset, deletedTextLength);
}

IntPoint AccessibilityObjectAtspi::boundaryOffset(unsigned utf16Offset, TextGranularity granularity) const
{
    return Accessibility::retrieveValueFromMainThread<IntPoint>([this, utf16Offset, granularity]() -> IntPoint {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject)
            return { };

        VisiblePosition offsetPosition = m_coreObject->visiblePositionForIndex(utf16Offset);
        VisiblePosition startPosition, endPostion;
        switch (granularity) {
        case TextGranularity::Character:
            RELEASE_ASSERT_NOT_REACHED();
        case TextGranularity::WordStart: {
            startPosition = isStartOfWord(offsetPosition) && deprecatedIsEditingWhitespace(offsetPosition.characterBefore()) ? offsetPosition : startOfWord(offsetPosition, LeftWordIfOnBoundary);
            endPostion = nextWordPosition(startPosition);
            auto positionAfterSpacingAndFollowingWord = nextWordPosition(endPostion);
            if (positionAfterSpacingAndFollowingWord != endPostion) {
                auto previousPosition = previousWordPosition(positionAfterSpacingAndFollowingWord);
                if (previousPosition == startPosition)
                    endPostion = positionAfterSpacingAndFollowingWord;
                else
                    endPostion = previousPosition;
            }
            break;
        }
        case TextGranularity::WordEnd: {
            startPosition = previousWordPosition(offsetPosition);
            auto positionBeforeSpacingAndPreviousWord = previousWordPosition(startPosition);
            if (positionBeforeSpacingAndPreviousWord != startPosition)
                startPosition = nextWordPosition(positionBeforeSpacingAndPreviousWord);
            endPostion = endOfWord(offsetPosition);
            break;
        }
        case TextGranularity::SentenceStart: {
            startPosition = startOfSentence(offsetPosition);
            endPostion = endOfSentence(startPosition);
            if (offsetPosition == endPostion) {
                startPosition = nextSentencePosition(startPosition);
                endPostion = endOfSentence(startPosition);
            }
            break;
        }
        case TextGranularity::SentenceEnd:
            startPosition = previousSentencePosition(offsetPosition);
            endPostion = endOfSentence(offsetPosition);
            break;
        case TextGranularity::LineStart:
            startPosition = logicalStartOfLine(offsetPosition);
            endPostion = nextLinePosition(offsetPosition, 0);
            break;
        case TextGranularity::LineEnd:
            startPosition = logicalStartOfLine(offsetPosition);
            endPostion = logicalEndOfLine(offsetPosition);
            break;
        case TextGranularity::Paragraph:
            startPosition = startOfParagraph(offsetPosition);
            endPostion = endOfParagraph(offsetPosition);
            break;
        }
        return { m_coreObject->indexForVisiblePosition(startPosition), m_coreObject->indexForVisiblePosition(endPostion) };
    });
}

CString AccessibilityObjectAtspi::textAtOffset(int offset, TextGranularity granularity, int& startOffset, int& endOffset) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return { };

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    if (offset < 0 || offset > length)
        return { };

    if (granularity == TextGranularity::Character) {
        startOffset = offset;
        endOffset = std::min(offset + 1, length);
    } else {
        auto mapping = offsetMapping(utf16Text);
        auto utf16Offset = UTF8OffsetToUTF16(mapping, offset);
        auto boundaryOffset = this->boundaryOffset(utf16Offset, granularity);
        startOffset = UTF16OffsetToUTF8(mapping, std::max<int>(boundaryOffset.x(), 0));
        endOffset = UTF16OffsetToUTF8(mapping, std::min<int>(boundaryOffset.y(), utf16Text.length()));
    }

    GUniquePtr<char> substring(g_utf8_substring(utf8Text.data(), startOffset, endOffset));
    return substring.get();
}

int AccessibilityObjectAtspi::characterAtOffset(int offset) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf8Text = text().utf8();
    if (utf8Text.isNull())
        return 0;

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    if (offset < 0 || offset >= length)
        return 0;

    return g_utf8_get_char(g_utf8_offset_to_pointer(utf8Text.data(), offset));
}

std::optional<unsigned> AccessibilityObjectAtspi::characterOffset(UChar character, int index) const
{
    auto utf16Text = text();
    unsigned start = 0;
    size_t offset;
    while ((offset = utf16Text.find(character, start)) != notFound) {
        start = offset + 1;
        if (!index)
            break;
        index--;
    }

    if (offset == notFound)
        return std::nullopt;

    auto mapping = offsetMapping(utf16Text);
    return UTF16OffsetToUTF8(mapping, offset);
}

std::optional<unsigned> AccessibilityObjectAtspi::characterIndex(UChar character, unsigned offset) const
{
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return std::nullopt;

    auto length = g_utf8_strlen(utf8Text.data(), -1);
    if (offset >= length)
        return std::nullopt;

    auto mapping = offsetMapping(utf16Text);
    auto utf16Offset = UTF8OffsetToUTF16(mapping, offset);
    if (utf16Text[utf16Offset] != character)
        return std::nullopt;

    unsigned start = 0;
    int index = -1;
    size_t position;
    while ((position = utf16Text.find(character, start)) != notFound) {
        index++;
        if (static_cast<unsigned>(position) == utf16Offset)
            break;
        start = position + 1;
    }

    if (index == -1)
        return std::nullopt;

    return index;
}

IntRect AccessibilityObjectAtspi::boundsForRange(unsigned utf16Offset, unsigned length, uint32_t coordinateType) const
{
    return Accessibility::retrieveValueFromMainThread<IntRect>([this, utf16Offset, length, coordinateType]() -> IntRect {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject)
            return { };

        auto extents = m_coreObject->doAXBoundsForRange(PlainTextRange(utf16Offset, length));

        auto* frameView = m_coreObject->documentFrameView();
        if (!frameView)
            return extents;

        switch (coordinateType) {
        case Atspi::CoordinateType::ScreenCoordinates:
            return frameView->contentsToScreen(extents);
        case Atspi::CoordinateType::WindowCoordinates:
            return frameView->contentsToWindow(extents);
        case Atspi::CoordinateType::ParentCoordinates:
            return extents;
        }

        RELEASE_ASSERT_NOT_REACHED();
    });
}

IntRect AccessibilityObjectAtspi::textExtents(int startOffset, int endOffset, uint32_t coordinateType) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return { };

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    startOffset = std::clamp(startOffset, 0, length);
    if (endOffset == -1)
        endOffset = length;
    else
        endOffset = std::clamp(endOffset, 0, length);
    if (endOffset <= startOffset)
        return { };

    auto mapping = offsetMapping(utf16Text);
    auto utf16StartOffset = UTF8OffsetToUTF16(mapping, startOffset);
    auto utf16EndOffset = UTF8OffsetToUTF16(mapping, endOffset);
    return boundsForRange(utf16StartOffset, utf16EndOffset - utf16StartOffset, coordinateType);
}

int AccessibilityObjectAtspi::offsetAtPoint(const IntPoint& point, uint32_t coordinateType) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return -1;

    auto utf16Offset = Accessibility::retrieveValueFromMainThread<int>([this, &point, coordinateType]() -> int {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject)
            return -1;

        auto convertedPoint = point;
        if (auto* frameView = m_coreObject->documentFrameView()) {
            switch (coordinateType) {
            case Atspi::CoordinateType::ScreenCoordinates:
                convertedPoint = frameView->screenToContents(point);
                break;
            case Atspi::CoordinateType::WindowCoordinates:
                convertedPoint = frameView->windowToContents(point);
                break;
            case Atspi::CoordinateType::ParentCoordinates:
                break;
            }
        }

        auto position = m_coreObject->visiblePositionForPoint(convertedPoint);
        if (position.isNull())
            return -1;

        return m_coreObject->indexForVisiblePosition(position);
    });

    if (utf16Offset == -1)
        return -1;

    return UTF16OffsetToUTF8(offsetMapping(utf16Text), utf16Offset);
}

IntPoint AccessibilityObjectAtspi::boundsForSelection(const VisibleSelection& selection) const
{
    RELEASE_ASSERT(isMainThread());
    if (selection.isNone())
        return { -1, -1 };

    Node* node = nullptr;
    if (!m_coreObject->isNativeTextControl())
        node = m_coreObject->node();
    else {
        auto positionInTextControlInnerElement = m_coreObject->visiblePositionForIndex(0);
        if (auto* innerMostNode = positionInTextControlInnerElement.deepEquivalent().anchorNode())
            node = innerMostNode->parentNode();
    }
    if (!node)
        return { -1, -1 };

    // We need to limit our search to positions that fall inside the domain of the current object.
    auto firstValidPosition = firstPositionInOrBeforeNode(node->firstDescendant());
    auto lastValidPosition = lastPositionInOrAfterNode(node->lastDescendant());

    if (!intersects(makeVisiblePositionRange(makeSimpleRange(firstValidPosition, lastValidPosition)), VisiblePositionRange(selection)))
        return { -1, -1 };

    // Find the proper range for the selection that falls inside the object.
    auto nodeRangeStart = std::max(selection.start(), firstValidPosition);
    auto nodeRangeEnd = std::min(selection.end(), lastValidPosition);

    // Calculate position of the selected range inside the object.
    auto parentFirstPosition = firstPositionInOrBeforeNode(node);
    auto rangeInParent = *makeSimpleRange(parentFirstPosition, nodeRangeStart);

    // Set values for start offsets and calculate initial range length.
    int startOffset = characterCount(rangeInParent, TextIteratorBehavior::EmitsObjectReplacementCharacters);
    auto nodeRange = *makeSimpleRange(nodeRangeStart, nodeRangeEnd);
    int rangeLength = characterCount(nodeRange, TextIteratorBehavior::EmitsObjectReplacementCharacters);
    return { startOffset, startOffset + rangeLength };
}

IntPoint AccessibilityObjectAtspi::selectedRange() const
{
    return Accessibility::retrieveValueFromMainThread<IntPoint>([this]() -> IntPoint {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject)
            return { -1, -1 };

        return boundsForSelection(m_coreObject->selection());
    });
}

bool AccessibilityObjectAtspi::selectionBounds(int& startOffset, int& endOffset) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return false;

    auto bounds = selectedRange();
    if (bounds.x() < 0)
        return false;

    auto mapping = offsetMapping(utf16Text);
    startOffset = UTF16OffsetToUTF8(mapping, bounds.x());
    endOffset = UTF16OffsetToUTF8(mapping, bounds.y());

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    endOffset = std::clamp(endOffset, 0, length);
    if (endOffset < startOffset) {
        startOffset = endOffset = 0;
        return false;
    }

    return true;
}

void AccessibilityObjectAtspi::setSelectedRange(unsigned utf16Offset, unsigned length)
{
    Accessibility::performFunctionOnMainThread([this, utf16Offset, length] {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject)
            return;

        auto range = m_coreObject->visiblePositionRangeForRange(PlainTextRange(utf16Offset, length));
        m_coreObject->setSelectedVisiblePositionRange(range);
    });
}

bool AccessibilityObjectAtspi::selectRange(int startOffset, int endOffset)
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return false;

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    startOffset = std::clamp(startOffset, 0, length);
    if (endOffset == -1)
        endOffset = length;
    else
        endOffset = std::clamp(endOffset, 0, length);

    auto mapping = offsetMapping(utf16Text);
    auto utf16StartOffset = UTF8OffsetToUTF16(mapping, startOffset);
    auto utf16EndOffset = startOffset == endOffset ? utf16StartOffset : UTF8OffsetToUTF16(mapping, endOffset);
    setSelectedRange(utf16StartOffset, utf16EndOffset - utf16StartOffset);

    return true;
}

void AccessibilityObjectAtspi::selectionChanged(const VisibleSelection& selection)
{
    RELEASE_ASSERT(isMainThread());
    if (!m_isRegistered.load())
        return;

    if (!m_interfaces.contains(Interface::Text))
        return;

    if (selection.isNone())
        return;

    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return;

    auto bounds = boundsForSelection(selection);
    if (bounds.y() < 0)
        return;

    auto length = g_utf8_strlen(utf8Text.data(), -1);
    auto mapping = offsetMapping(utf16Text);
    auto caretOffset = UTF16OffsetToUTF8(mapping, bounds.y());
    if (caretOffset <= length)
        root()->atspi().textCaretMoved(*this, caretOffset);

    if (selection.isRange())
        root()->atspi().textSelectionChanged(*this);
}

AccessibilityObjectAtspi::TextAttributes AccessibilityObjectAtspi::textAttributes(std::optional<unsigned> utf16Offset, bool includeDefault) const
{
    return Accessibility::retrieveValueFromMainThread<TextAttributes>([this, utf16Offset, includeDefault]() -> TextAttributes {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject || !m_coreObject->renderer() || !m_coreObject->node())
            return { };

        auto accessibilityTextAttributes = [this](AXCoreObject* axObject, const HashMap<String, String>& defaultAttributes) -> HashMap<String, String> {
            HashMap<String, String> attributes;
            auto& style = axObject->renderer()->style();

            auto addAttributeIfNeeded = [&](const String& name, const String& value) {
                if (defaultAttributes.isEmpty() || defaultAttributes.get(name) != value)
                    attributes.add(name, value);
            };

            auto bgColor = style.visitedDependentColor(CSSPropertyBackgroundColor);
            if (bgColor.isValid() && bgColor.isVisible()) {
                auto [r, g, b, a] = bgColor.toSRGBALossy<uint8_t>();
                addAttributeIfNeeded("bg-color"_s, makeString(r, ',', g, ',', b));
            }

            auto fgColor = style.visitedDependentColor(CSSPropertyColor);
            if (fgColor.isValid() && fgColor.isVisible()) {
                auto [r, g, b, a] = fgColor.toSRGBALossy<uint8_t>();
                addAttributeIfNeeded("fg-color"_s, makeString(r, ',', g, ',', b));
            }

            addAttributeIfNeeded("family-name"_s, style.fontCascade().firstFamily());
            addAttributeIfNeeded("size"_s, makeString(std::round(style.computedFontPixelSize() * 72 / WebCore::screenDPI()), "pt"));
            addAttributeIfNeeded("weight"_s, makeString(static_cast<float>(style.fontCascade().weight())));
            addAttributeIfNeeded("style"_s, style.fontCascade().italic() ? "italic" : "normal");
            addAttributeIfNeeded("strikethrough"_s, style.textDecoration() & TextDecorationLine::LineThrough ? "true" : "false");
            addAttributeIfNeeded("underline"_s, style.textDecoration() & TextDecorationLine::Underline ? "single" : "none");
            addAttributeIfNeeded("invisible"_s, style.visibility() == Visibility::Hidden ? "true" : "false");
            addAttributeIfNeeded("editable"_s, m_coreObject->canSetValueAttribute() ? "true" : "false");
            addAttributeIfNeeded("direction"_s, style.direction() == TextDirection::LTR ? "ltr" : "rtl");

            if (!style.textIndent().isUndefined())
                addAttributeIfNeeded("indent"_s, makeString(valueForLength(style.textIndent(), m_coreObject->size().width()).toInt()));

            switch (style.textAlign()) {
            case TextAlignMode::Start:
            case TextAlignMode::End:
                break;
            case TextAlignMode::Left:
            case TextAlignMode::WebKitLeft:
                addAttributeIfNeeded("justification"_s, "left");
                break;
            case TextAlignMode::Right:
            case TextAlignMode::WebKitRight:
                addAttributeIfNeeded("justification"_s, "right");
                break;
            case TextAlignMode::Center:
            case TextAlignMode::WebKitCenter:
                addAttributeIfNeeded("justification"_s, "center");
                break;
            case TextAlignMode::Justify:
                addAttributeIfNeeded("justification"_s, "fill");
                break;
            }

            String invalidStatus = m_coreObject->invalidStatus();
            if (invalidStatus != "false")
                addAttributeIfNeeded("invalid"_s, invalidStatus);

            String language = m_coreObject->language();
            if (!language.isEmpty())
                addAttributeIfNeeded("language"_s, language);

            return attributes;
        };

        auto defaultAttributes = accessibilityTextAttributes(m_coreObject, { });
        if (!utf16Offset)
            return { defaultAttributes, -1, -1 };

        VisiblePosition offsetPosition = m_coreObject->visiblePositionForIndex(*utf16Offset);
        auto* childNode = offsetPosition.deepEquivalent().deprecatedNode();
        if (!childNode)
            return { defaultAttributes, -1, -1 };

        auto* childRenderer = childNode->renderer();
        if (!childRenderer)
            return { defaultAttributes, -1, -1 };

        auto* childAxObject = childRenderer->document().axObjectCache()->get(childRenderer);
        if (!childAxObject || childAxObject == m_coreObject)
            return { defaultAttributes, -1, -1 };

        auto attributes = accessibilityTextAttributes(childAxObject, defaultAttributes);
        auto firstValidPosition = firstPositionInOrBeforeNode(m_coreObject->node()->firstDescendant());
        auto lastValidPosition = lastPositionInOrAfterNode(m_coreObject->node()->lastDescendant());

        auto* startRenderer = childRenderer;
        auto startPosition = firstPositionInOrBeforeNode(startRenderer->node());
        for (RenderObject* r = childRenderer->previousInPreOrder(); r && startPosition > firstValidPosition; r = r->previousInPreOrder()) {
            if (r->firstChildSlow())
                continue;

            auto childAttributes = accessibilityTextAttributes(r->document().axObjectCache()->get(r), defaultAttributes);
            if (childAttributes != attributes)
                break;

            startRenderer = r;
            startPosition = firstPositionInOrBeforeNode(startRenderer->node());
        }

        auto* endRenderer = childRenderer;
        auto endPosition = lastPositionInOrAfterNode(endRenderer->node());
        for (RenderObject* r = childRenderer->nextInPreOrder(); r && endPosition < lastValidPosition; r = r->nextInPreOrder()) {
            if (r->firstChildSlow())
                continue;

            auto childAttributes = accessibilityTextAttributes(r->document().axObjectCache()->get(r), defaultAttributes);
            if (childAttributes != attributes)
                break;

            endRenderer = r;
            endPosition = lastPositionInOrAfterNode(endRenderer->node());
        }

        if (!includeDefault)
            return { attributes, m_coreObject->indexForVisiblePosition(startPosition), m_coreObject->indexForVisiblePosition(endPosition) };

        for (const auto& it : attributes)
            defaultAttributes.set(it.key, it.value);

        return { defaultAttributes, m_coreObject->indexForVisiblePosition(startPosition), m_coreObject->indexForVisiblePosition(endPosition) };
    });
}

AccessibilityObjectAtspi::TextAttributes AccessibilityObjectAtspi::textAttributesWithUTF8Offset(std::optional<int> offset, bool includeDefault) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return { };

    auto mapping = offsetMapping(utf16Text);
    std::optional<unsigned> utf16Offset;
    if (offset) {
        auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
        if (*offset < 0 || *offset >= length)
            return { };

        utf16Offset = UTF8OffsetToUTF16(mapping, *offset);
    }

    auto attributes = textAttributes(utf16Offset, includeDefault);
    if (attributes.startOffset != -1)
        attributes.startOffset = UTF16OffsetToUTF8(mapping, attributes.startOffset);
    if (attributes.endOffset != -1)
        attributes.endOffset = UTF16OffsetToUTF8(mapping, attributes.endOffset);

    return attributes;
}

void AccessibilityObjectAtspi::textAttributesChanged()
{
    RELEASE_ASSERT(isMainThread());
    if (!m_isRegistered.load())
        return;

    if (!m_interfaces.contains(Interface::Text))
        return;

    root()->atspi().textAttributesChanged(*this);
}

bool AccessibilityObjectAtspi::scrollToMakeVisible(int startOffset, int endOffset, uint32_t scrollType) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return false;

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    if (startOffset < 0 || startOffset > length)
        return false;
    if (endOffset < 0 || endOffset > length)
        return false;
    if (endOffset < startOffset)
        std::swap(startOffset, endOffset);

    auto mapping = offsetMapping(utf16Text);
    auto utf16StartOffset = UTF8OffsetToUTF16(mapping, startOffset);
    auto utf16EndOffset = UTF8OffsetToUTF16(mapping, endOffset);
    Accessibility::performFunctionOnMainThread([this, utf16StartOffset, utf16EndOffset, scrollType] {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

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

        IntRect rect = m_coreObject->doAXBoundsForRange(PlainTextRange(utf16StartOffset, utf16EndOffset - utf16StartOffset));

        if (m_coreObject->isScrollView()) {
            if (auto* parent = m_coreObject->parentObject())
                parent->scrollToMakeVisible();
        }

        ScrollAlignment alignX;
        ScrollAlignment alignY;
        switch (scrollType) {
        case Atspi::ScrollType::TopLeft:
            alignX = ScrollAlignment::alignLeftAlways;
            alignY = ScrollAlignment::alignTopAlways;
            break;
        case Atspi::ScrollType::BottomRight:
            alignX = ScrollAlignment::alignRightAlways;
            alignY = ScrollAlignment::alignBottomAlways;
            break;
        case Atspi::ScrollType::TopEdge:
        case Atspi::ScrollType::BottomEdge:
            // Align to a particular edge is not supported, it's always the closest edge.
            alignX = ScrollAlignment::alignCenterIfNeeded;
            alignY = ScrollAlignment::alignToEdgeIfNeeded;
            break;
        case Atspi::ScrollType::LeftEdge:
        case Atspi::ScrollType::RightEdge:
            // Align to a particular edge is not supported, it's always the closest edge.
            alignX = ScrollAlignment::alignToEdgeIfNeeded;
            alignY = ScrollAlignment::alignCenterIfNeeded;
            break;
        case Atspi::ScrollType::Anywhere:
            alignX = ScrollAlignment::alignCenterIfNeeded;
            alignY = ScrollAlignment::alignCenterIfNeeded;
            break;
        }

        m_coreObject->renderer()->scrollRectToVisible(rect, false, { SelectionRevealMode::Reveal, alignX, alignY, ShouldAllowCrossOriginScrolling::Yes });
    });

    return true;
}

bool AccessibilityObjectAtspi::scrollToPoint(int startOffset, int endOffset, uint32_t coordinateType, int x, int y) const
{
    RELEASE_ASSERT(!isMainThread());
    auto utf16Text = text();
    auto utf8Text = utf16Text.utf8();
    if (utf8Text.isNull())
        return false;

    auto length = static_cast<int>(g_utf8_strlen(utf8Text.data(), -1));
    if (startOffset < 0 || startOffset > length)
        return false;
    if (endOffset < 0 || endOffset > length)
        return false;
    if (endOffset < startOffset)
        std::swap(startOffset, endOffset);

    auto mapping = offsetMapping(utf16Text);
    auto utf16StartOffset = UTF8OffsetToUTF16(mapping, startOffset);
    auto utf16EndOffset = UTF8OffsetToUTF16(mapping, endOffset);
    Accessibility::performFunctionOnMainThread([this, utf16StartOffset, utf16EndOffset, coordinateType, x, y] {
        if (m_coreObject)
            m_coreObject->updateBackingStore();

        if (!m_coreObject)
            return;

        IntPoint point(x, y);
        if (coordinateType == Atspi::CoordinateType::ScreenCoordinates) {
            if (auto* frameView = m_coreObject->documentFrameView())
                point = frameView->contentsToWindow(frameView->screenToContents(point));
        }

        IntRect rect = m_coreObject->doAXBoundsForRange(PlainTextRange(utf16StartOffset, utf16EndOffset - utf16StartOffset));
        point.move(-rect.x(), -rect.y());
        m_coreObject->scrollToGlobalPoint(point);
    });

    return true;
}

} // namespace WebCore

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