/*
 * 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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 "AccessibilityNotificationHandler.h"

#if HAVE(ACCESSIBILITY) && USE(ATSPI)
#include "InjectedBundlePage.h"
#include "JSWrapper.h"
#include <JavaScriptCore/OpaqueJSString.h>
#include <WebCore/AccessibilityObjectAtspi.h>
#include <WebKit/WKBundleFrame.h>
#include <WebKit/WKBundlePage.h>
#include <WebKit/WKBundlePagePrivate.h>

namespace WTR {

AccessibilityNotificationHandler::AccessibilityNotificationHandler(JSValueRef callback, PlatformUIElement element)
    : m_callback(callback)
    , m_element(element)
{
    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
    JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
    JSValueProtect(jsContext, m_callback);

    WebCore::AccessibilityAtspi::singleton().addNotificationObserver(this, [this](WebCore::AccessibilityObjectAtspi& element, const char* notificationName, WebCore::AccessibilityAtspi::NotificationObserverParameter parameter) {
        if (m_element && m_element.get() != &element)
            return;

        WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
        JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);

        JSRetainPtr<JSStringRef> jsNotificationEventName(Adopt, JSStringCreateWithUTF8CString(notificationName));
        JSValueRef jsParameter = WTF::switchOn(parameter,
            [&](String& stringValue) -> JSValueRef {
                JSRetainPtr<JSStringRef> jsStringValue(Adopt, OpaqueJSString::tryCreate(stringValue).get());
                return JSValueMakeString(jsContext, jsStringValue.get());
            },
            [&](bool& boolValue) -> JSValueRef {
                return JSValueMakeBoolean(jsContext, boolValue);
            },
            [&](unsigned& unsignedValue) -> JSValueRef {
                return JSValueMakeNumber(jsContext, unsignedValue);
            },
            [&](Ref<WebCore::AccessibilityObjectAtspi>& elementValue) -> JSValueRef {
                return toJS(jsContext, AccessibilityUIElement::create(elementValue.ptr()).ptr());
            },
            [&](auto&) -> JSValueRef {
                return JSValueMakeUndefined(jsContext);
            });

        if (m_element) {
            // Listener for one element gets the notification name parameter.
            JSValueRef arguments[2];
            arguments[0] = JSValueMakeString(jsContext, jsNotificationEventName.get());
            arguments[1] = jsParameter;
            JSObjectCallAsFunction(jsContext, const_cast<JSObjectRef>(m_callback), 0, 2, arguments, 0);
        } else {
            // A global listener gets the element, notification name and parameter.
            JSValueRef arguments[3];
            arguments[0] = toJS(jsContext, AccessibilityUIElement::create(&element).ptr());
            arguments[1] = JSValueMakeString(jsContext, jsNotificationEventName.get());
            arguments[2] = jsParameter;
            JSObjectCallAsFunction(jsContext, const_cast<JSObjectRef>(m_callback), 0, 3, arguments, 0);
        }
    });
}

AccessibilityNotificationHandler::~AccessibilityNotificationHandler()
{
    WebCore::AccessibilityAtspi::singleton().removeNotificationObserver(this);

    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
    JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
    JSValueUnprotect(jsContext, m_callback);
}

} // namespace WTR

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