/*
 * Copyright (C) 2015 Apple Inc. All rights reserved.
 *
 * 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. AND ITS 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 APPLE INC. OR ITS 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.
 */

#import "config.h"
#import "UIScriptControllerMac.h"

#if PLATFORM(MAC)

#import "DumpRenderTree.h"
#import "EventSendingController.h"
#import "LayoutTestSpellChecker.h"
#import "UIScriptContext.h"
#import <JavaScriptCore/JSContext.h>
#import <JavaScriptCore/JSStringRefCF.h>
#import <JavaScriptCore/JSValue.h>
#import <JavaScriptCore/OpaqueJSString.h>
#import <WebKit/WebPreferences.h>
#import <WebKit/WebViewPrivate.h>
#import <mach/mach_time.h>
#import <pal/spi/mac/NSTextInputContextSPI.h>
#import <wtf/WorkQueue.h>

namespace WTR {

Ref<UIScriptController> UIScriptController::create(UIScriptContext& context)
{
    return adoptRef(*new UIScriptControllerMac(context));
}

void UIScriptControllerMac::doAsyncTask(JSValueRef callback)
{
    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);

    WorkQueue::main().dispatch([this, protectedThis = Ref { *this }, callbackID] {
        if (!m_context)
            return;
        m_context->asyncTaskComplete(callbackID);
    });
}

void UIScriptControllerMac::replaceTextAtRange(JSStringRef text, int location, int length)
{
    auto textToInsert = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, text));
    auto rangeAttribute = adoptNS([[NSDictionary alloc] initWithObjectsAndKeys:NSStringFromRange(NSMakeRange(location == -1 ? NSNotFound : location, length)), NSTextInputReplacementRangeAttributeName, nil]);
    auto textAndRange = adoptNS([[NSAttributedString alloc] initWithString:(__bridge NSString *)textToInsert.get() attributes:rangeAttribute.get()]);

    [mainFrame.webView insertText:textAndRange.get()];
}

void UIScriptControllerMac::zoomToScale(double scale, JSValueRef callback)
{
    WebView *webView = [mainFrame webView];
    [webView _scaleWebView:scale atOrigin:NSZeroPoint];

    doAsyncTask(callback);
}

double UIScriptControllerMac::zoomScale() const
{
    return mainFrame.webView._viewScaleFactor;
}

void UIScriptControllerMac::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)
{
    NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
    [center postNotificationName:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification object:[mainFrame webView]];

    doAsyncTask(callback);
}

JSObjectRef UIScriptControllerMac::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
{
#if JSC_OBJC_API_ENABLED
    WebView *webView = [mainFrame webView];
    RetainPtr<CFStringRef> interfaceItemCF = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, interfaceItem));
    NSDictionary *contentDictionary = [webView _contentsOfUserInterfaceItem:(__bridge NSString *)interfaceItemCF.get()];
    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:contentDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
#else
    UNUSED_PARAM(interfaceItem);
    return nullptr;
#endif
}

void UIScriptControllerMac::activateDataListSuggestion(unsigned index, JSValueRef callback)
{
    // FIXME: Not implemented.
    UNUSED_PARAM(index);

    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
    WorkQueue::main().dispatch([this, protectedThis = Ref { *this }, callbackID] {
        if (!m_context)
            return;
        m_context->asyncTaskComplete(callbackID);
    });
}

void UIScriptControllerMac::overridePreference(JSStringRef preferenceRef, JSStringRef valueRef)
{
    WebPreferences *preferences = mainFrame.webView.preferences;

    RetainPtr<CFStringRef> value = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, valueRef));
    if (JSStringIsEqualToUTF8CString(preferenceRef, "WebKitMinimumFontSize"))
        preferences.minimumFontSize = [(__bridge NSString *)value.get() doubleValue];
}

void UIScriptControllerMac::removeViewFromWindow(JSValueRef callback)
{
    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);

    WebView *webView = [mainFrame webView];
    [webView removeFromSuperview];

    WorkQueue::main().dispatch([this, protectedThis = Ref { *this }, callbackID] {
        if (!m_context)
            return;
        m_context->asyncTaskComplete(callbackID);
    });
}

void UIScriptControllerMac::addViewToWindow(JSValueRef callback)
{
    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);

    WebView *webView = [mainFrame webView];
    [[mainWindow contentView] addSubview:webView];

    WorkQueue::main().dispatch([this, protectedThis = Ref { *this }, callbackID] {
        if (!m_context)
            return;
        m_context->asyncTaskComplete(callbackID);
    });
}

void UIScriptControllerMac::toggleCapsLock(JSValueRef callback)
{
    doAsyncTask(callback);
}

NSUndoManager *UIScriptControllerMac::platformUndoManager() const
{
    return nil;
}

void UIScriptControllerMac::copyText(JSStringRef text)
{
    NSPasteboard *pasteboard = NSPasteboard.generalPasteboard;
    [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil];
    [pasteboard setString:text->string() forType:NSPasteboardTypeString];
}

void UIScriptControllerMac::setSpellCheckerResults(JSValueRef results)
{
    [[LayoutTestSpellChecker checker] setResultsFromJSValue:results inContext:m_context->jsContext()];
}

static NSString *const TopLevelEventInfoKey = @"events";
static NSString *const EventTypeKey = @"type";
static NSString *const ViewRelativeXPositionKey = @"viewX";
static NSString *const ViewRelativeYPositionKey = @"viewY";
static NSString *const DeltaXKey = @"deltaX";
static NSString *const DeltaYKey = @"deltaY";
static NSString *const PhaseKey = @"phase";
static NSString *const MomentumPhaseKey = @"momentumPhase";

static CGGesturePhase gesturePhaseFromString(NSString *phaseStr)
{
    if ([phaseStr isEqualToString:@"began"])
        return kCGGesturePhaseBegan;

    if ([phaseStr isEqualToString:@"changed"])
        return kCGGesturePhaseChanged;

    if ([phaseStr isEqualToString:@"ended"])
        return kCGGesturePhaseEnded;

    if ([phaseStr isEqualToString:@"cancelled"])
        return kCGGesturePhaseCancelled;

    if ([phaseStr isEqualToString:@"maybegin"])
        return kCGGesturePhaseMayBegin;

    return kCGGesturePhaseNone;
}

static CGMomentumScrollPhase momentumPhaseFromString(NSString *phaseStr)
{
    if ([phaseStr isEqualToString:@"began"])
        return kCGMomentumScrollPhaseBegin;

    if ([phaseStr isEqualToString:@"changed"] || [phaseStr isEqualToString:@"continue"]) // Allow "continue" for ease of conversion from mouseScrollByWithWheelAndMomentumPhases values.
        return kCGMomentumScrollPhaseContinue;

    if ([phaseStr isEqualToString:@"ended"])
        return kCGMomentumScrollPhaseEnd;

    return kCGMomentumScrollPhaseNone;
}

static EventSendingController *eventSenderFromView(WebView *webView)
{
    auto frame = [webView mainFrame];
    auto windowObject = [frame windowObject];
    return [windowObject valueForKey:@"eventSender"];
}

void UIScriptControllerMac::sendEventStream(JSStringRef eventsJSON, JSValueRef callback)
{
    WebView *webView = [mainFrame webView];

    // didClearWindowObjectInStandardWorldForFrame stashed EventSendingController on this window property.
    EventSendingController* eventSender = eventSenderFromView(webView);
    if (!eventSender) {
        ASSERT_NOT_REACHED();
        return;
    }

    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);

    auto jsonString = eventsJSON->string();
    auto eventInfo = dynamic_objc_cast<NSDictionary>([NSJSONSerialization JSONObjectWithData:[(NSString *)jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil]);
    if (!eventInfo || ![eventInfo isKindOfClass:[NSDictionary class]]) {
        WTFLogAlways("JSON is not convertible to a dictionary");
        return;
    }

    double currentViewRelativeX = 0;
    double currentViewRelativeY = 0;

    constexpr uint64_t nanosecondsPerSecond = 1e9;
    constexpr uint64_t nanosecondsEventInterval = nanosecondsPerSecond / 60;

    auto currentTime = mach_absolute_time();

    for (NSMutableDictionary *event in eventInfo[TopLevelEventInfoKey]) {

        id eventType = event[EventTypeKey];
        if (!event[EventTypeKey]) {
            WTFLogAlways("Missing event type");
            break;
        }
        
        if ([eventType isEqualToString:@"wheel"]) {
            auto phase = kCGGesturePhaseNone;
            auto momentumPhase = kCGMomentumScrollPhaseNone;

            if (!event[PhaseKey] && !event[MomentumPhaseKey]) {
                WTFLogAlways("Event must specify phase or momentumPhase");
                break;
            }

            if (id phaseString = event[PhaseKey])
                phase = gesturePhaseFromString(phaseString);

            if (id phaseString = event[MomentumPhaseKey])
                momentumPhase = momentumPhaseFromString(phaseString);

            ASSERT_IMPLIES(phase == kCGGesturePhaseNone, momentumPhase != kCGMomentumScrollPhaseNone);
            ASSERT_IMPLIES(momentumPhase == kCGMomentumScrollPhaseNone, phase != kCGGesturePhaseNone);

            if (event[ViewRelativeXPositionKey])
                currentViewRelativeX = [event[ViewRelativeXPositionKey] floatValue];

            if (event[ViewRelativeYPositionKey])
                currentViewRelativeY = [event[ViewRelativeYPositionKey] floatValue];

            double deltaX = 0;
            double deltaY = 0;

            if (event[DeltaXKey])
                deltaX = [event[DeltaXKey] floatValue];

            if (event[DeltaYKey])
                deltaY = [event[DeltaYKey] floatValue];

            auto windowPoint = [webView convertPoint:CGPointMake(currentViewRelativeX, [webView frame].size.height - currentViewRelativeY) toView:nil];
            [eventSender sendScrollEventAt:windowPoint deltaX:deltaX deltaY:deltaY units:kCGScrollEventUnitPixel wheelPhase:phase momentumPhase:momentumPhase timestamp:currentTime];
        }

        currentTime += nanosecondsEventInterval;
    }

    WorkQueue::main().dispatch([this, strongThis = Ref { *this }, callbackID] {
        if (!m_context)
            return;
        m_context->asyncTaskComplete(callbackID);
    });
}

} // namespace WTR

#endif // PLATFORM(MAC)
