/*
 * 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 "AccessibilityRootAtspi.h"
#include <gio/gio.h>
#include <wtf/URL.h>
#include <wtf/unicode/CharacterNames.h>

namespace WebCore {

GDBusInterfaceVTable AccessibilityObjectAtspi::s_hyperlinkFunctions = {
    // 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, "GetObject")) {
            int index;
            g_variant_get(parameters, "(i)", &index);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(@(so))", !index ? atspiObject->reference() : atspiObject->root()->atspi().nullReference()));
        } else if (!g_strcmp0(methodName, "GetURI")) {
            int index;
            g_variant_get(parameters, "(i)", &index);
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", !index ? atspiObject->url().string().utf8().data() : ""));
        } else if (!g_strcmp0(methodName, "IsValid"))
            g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", atspiObject->m_axObject ? TRUE : FALSE));
    },
    // 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, "NAnchors"))
            return g_variant_new_int32(1);
        if (!g_strcmp0(propertyName, "StartIndex"))
            return g_variant_new_int32(atspiObject->offsetInParent());
        if (!g_strcmp0(propertyName, "EndIndex"))
            return g_variant_new_int32(atspiObject->offsetInParent() + 1);

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

URL AccessibilityObjectAtspi::url() const
{
    AXCoreObject* axObject = isMainThread() ? m_coreObject : m_axObject;
    return axObject ? axObject->url() : URL();
}

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

        if (!m_coreObject)
            return 0;

        auto* parent = m_coreObject->parentObjectUnignored();
        if (!parent || !parent->wrapper())
            return 0;

        int index = -1;
        const auto& children = parent->children();
        for (const auto& child : children) {
            if (child->accessibilityIsIgnored())
                continue;

            auto* wrapper = child->wrapper();
            if (!wrapper || !wrapper->interfaces().contains(Interface::Hyperlink))
                continue;

            index++;
            if (wrapper == this)
                break;
        }

        if (index == -1)
            return 0;

        return parent->wrapper()->characterOffset(objectReplacementCharacter, index).value_or(0);
    });
}

} // namespace WebCore

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