/*
 * Copyright (C) 2016 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 "EventSerializerMac.h"

#if PLATFORM(MAC)

#import "CoreGraphicsTestSPI.h"
#import <algorithm>
#import <mach/mach_time.h>
#import <pal/spi/cocoa/IOKitSPI.h>
#import <wtf/RetainPtr.h>

#define MOUSE_EVENT_TYPES \
    (CGSEventType)kCGEventLeftMouseDown, \
    (CGSEventType)kCGEventLeftMouseUp, \
    (CGSEventType)kCGEventRightMouseDown, \
    (CGSEventType)kCGEventRightMouseUp, \
    (CGSEventType)kCGEventMouseMoved, \
    (CGSEventType)kCGEventLeftMouseDragged, \
    (CGSEventType)kCGEventRightMouseDragged, \
    (CGSEventType)kCGEventOtherMouseDown, \
    (CGSEventType)kCGEventOtherMouseUp, \
    (CGSEventType)kCGEventOtherMouseDragged

#define KEY_EVENT_TYPES \
    (CGSEventType)kCGEventKeyDown, \
    (CGSEventType)kCGEventKeyUp, \
    (CGSEventType)kCGEventFlagsChanged

#define GESTURE_EVENT_TYPES \
    kCGSEventGesture, \
    kCGSEventFluidTouchGesture, \
    kCGSEventDockControl

bool eventIsOfType(CGEventRef event, CGSEventType type)
{
    return (CGSEventType)CGEventGetType(event) == type;
}

bool eventIsOfTypes(CGEventRef) { return false; }

template<typename ... Types>
bool eventIsOfTypes(CGEventRef event, CGSEventType first, Types ... rest)
{
    return eventIsOfType(event, first) || eventIsOfTypes(event, rest...);
}

bool eventIsOfGestureType(CGEventRef event, IOHIDEventType type)
{
    return (IOHIDEventType)CGEventGetIntegerValueField(event, kCGEventGestureHIDType) == type;
}

bool eventIsOfGestureTypes(CGEventRef) { return false; }

template<typename ... Types>
bool eventIsOfGestureTypes(CGEventRef event, IOHIDEventType first, Types ... rest)
{
    if (!eventIsOfTypes(event, GESTURE_EVENT_TYPES))
        return false;
    return eventIsOfGestureType(event, first) || eventIsOfGestureTypes(event, rest...);
}

#define FOR_EACH_CGEVENT_INTEGER_FIELD(macro) \
    macro(true, kCGSEventTypeField) \
    \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventDeltaAxis1) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventDeltaAxis2) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventDeltaAxis3) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventIsContinuous) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventMomentumPhase) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventPointDeltaAxis1) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventPointDeltaAxis2) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventPointDeltaAxis3) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventScrollCount) \
    macro(eventIsOfTypes(rawEvent, kCGSEventScrollWheel, kCGSEventZoom), kCGScrollWheelEventScrollPhase) \
    \
    macro(eventIsOfTypes(rawEvent, MOUSE_EVENT_TYPES), kCGMouseEventButtonNumber) \
    macro(eventIsOfTypes(rawEvent, MOUSE_EVENT_TYPES), kCGMouseEventClickState) \
    macro(eventIsOfTypes(rawEvent, MOUSE_EVENT_TYPES), kCGMouseEventDeltaX) \
    macro(eventIsOfTypes(rawEvent, MOUSE_EVENT_TYPES), kCGMouseEventDeltaY) \
    macro(eventIsOfTypes(rawEvent, MOUSE_EVENT_TYPES), kCGMouseEventSubtype) \
    macro(eventIsOfTypes(rawEvent, MOUSE_EVENT_TYPES), kCGMouseEventNumber) \
    \
    macro(eventIsOfTypes(rawEvent, KEY_EVENT_TYPES), kCGKeyboardEventAutorepeat) \
    macro(eventIsOfTypes(rawEvent, KEY_EVENT_TYPES), kCGKeyboardEventKeyboardType) \
    macro(eventIsOfTypes(rawEvent, KEY_EVENT_TYPES), kCGKeyboardEventKeycode) \
    \
    macro(eventIsOfTypes(rawEvent, GESTURE_EVENT_TYPES), kCGEventGestureHIDType) \
    macro(eventIsOfTypes(rawEvent, GESTURE_EVENT_TYPES), kCGEventGestureBehavior) \
    macro(eventIsOfTypes(rawEvent, GESTURE_EVENT_TYPES), kCGEventGestureFlavor) \
    macro(eventIsOfTypes(rawEvent, GESTURE_EVENT_TYPES), kCGEventGestureMask) \
    macro(eventIsOfTypes(rawEvent, GESTURE_EVENT_TYPES), kCGEventGesturePhase) \
    macro(eventIsOfTypes(rawEvent, GESTURE_EVENT_TYPES), kCGEventGestureStage) \
    \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeScroll), kCGEventScrollGestureFlagBits) \
    \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventSwipeGestureFlagBits) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipeMask) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipeMotion) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipeValue) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureFlavor) \
    \
    macro(eventIsOfGestureTypes(rawEvent, kCGHIDEventTypeGestureStarted, kCGHIDEventTypeGestureEnded), kCGEventGestureStartEndSeriesType)

#define FOR_EACH_CGEVENT_DOUBLE_FIELD(macro) \
    macro(eventIsOfTypes(rawEvent, GESTURE_EVENT_TYPES), kCGEventGestureProgress) \
    \
    macro(eventIsOfTypes(rawEvent, MOUSE_EVENT_TYPES), kCGMouseEventPressure) \
    \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeZoom), kCGEventGestureZoomDeltaX) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeZoom), kCGEventGestureZoomDeltaY) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeZoom), kCGEventGestureZoomValue) \
    \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeRotation), kCGEventGestureRotationValue) \
    \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeScroll), kCGEventGestureScrollX) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeScroll), kCGEventGestureScrollY) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeScroll), kCGEventGestureScrollZ) \
    \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipePositionX) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipePositionY) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipeProgress) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipeVelocityX) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipeVelocityY) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeNavigationSwipe), kCGEventGestureSwipeVelocityZ) \
    \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeForce), kCGEventTransitionProgress) \
    macro(eventIsOfGestureType(rawEvent, kIOHIDEventTypeForce), kCGEventStagePressure)

#define LOAD_INTEGER_FIELD_FROM_EVENT(eventTypeFilter, field) \
^ { \
    if (!(eventTypeFilter)) \
        return; \
    int64_t value = CGEventGetIntegerValueField(rawEvent, field); \
    int64_t plainValue = CGEventGetIntegerValueField(rawPlainEvent, field); \
    if (value != plainValue) \
        dict.get()[@#field] = @(value); \
}();

#define LOAD_DOUBLE_FIELD_FROM_EVENT(eventTypeFilter, field) \
^ { \
    if (!(eventTypeFilter)) \
        return; \
    double value = CGEventGetDoubleValueField(rawEvent, field); \
    if (!isnan(value)) { \
        double plainValue = CGEventGetDoubleValueField(rawPlainEvent, field); \
        if (fabs(value - plainValue) >= FLT_EPSILON) \
            dict.get()[@#field] = @(value); \
    } \
}();

#define STORE_INTEGER_FIELD_TO_EVENT(eventTypeFilter, field) \
^ { \
    if (!(eventTypeFilter)) \
        return; \
    NSNumber *value = dict[@#field]; \
    if (value) \
        CGEventSetIntegerValueField(rawEvent, field, value.unsignedLongLongValue); \
}();

#define STORE_DOUBLE_FIELD_TO_EVENT(eventTypeFilter, field) \
^ { \
    if (!(eventTypeFilter)) \
        return; \
    NSNumber *value = dict[@#field]; \
    if (value) \
        CGEventSetDoubleValueField(rawEvent, field, value.doubleValue); \
}();

@implementation EventSerializer

+ (NSDictionary *)dictionaryForEvent:(CGEventRef)rawEvent relativeToTime:(CGEventTimestamp)referenceTimestamp
{
    auto plainEvent = adoptCF(CGEventCreate(NULL));
    CGEventRef rawPlainEvent = plainEvent.get();

    auto dict = adoptNS([[NSMutableDictionary alloc] init]);

    FOR_EACH_CGEVENT_INTEGER_FIELD(LOAD_INTEGER_FIELD_FROM_EVENT);
    FOR_EACH_CGEVENT_DOUBLE_FIELD(LOAD_DOUBLE_FIELD_FROM_EVENT);

    CGEventTimestamp timestamp = CGEventGetTimestamp(rawEvent);
    dict.get()[@"relativeTimeMS"] = @(std::max(static_cast<double>(timestamp - referenceTimestamp) / NSEC_PER_MSEC, 0.0));

    CGSEventType eventType = (CGSEventType)CGEventGetIntegerValueField(rawEvent, kCGSEventTypeField);
    if (eventType == kCGSEventGesture || eventType == kCGSEventFluidTouchGesture || eventType == kCGSEventDockControl) {
        if (CGEventGetIntegerValueField(rawEvent, kCGEventGestureIsPreflight)) {
            dict.get()[@"kCGEventGestureIsPreflight"] = @YES;
            dict.get()[@"kCGEventGesturePreflightProgress"] = @(CGEventGetDoubleValueField(rawEvent, kCGEventGesturePreflightProgress));
        }
    }

    dict.get()[@"windowLocation"] = NSStringFromPoint(NSPointFromCGPoint(CGEventGetWindowLocation(rawEvent)));

    auto flags = static_cast<CGEventFlags>(CGEventGetFlags(rawEvent) & ~NX_NONCOALSESCEDMASK);
    auto plainFlags = static_cast<CGEventFlags>(CGEventGetFlags(rawPlainEvent) & ~NX_NONCOALSESCEDMASK);
    if (flags != plainFlags)
        dict.get()[@"flags"] = @(flags);

    return dict.autorelease();
}

+ (RetainPtr<CGEventRef>)createEventForDictionary:(NSDictionary *)dict inWindow:(NSWindow *)window relativeToTime:(CGEventTimestamp)referenceTimestamp
{
    auto event = adoptCF(CGEventCreate(NULL));
    CGEventRef rawEvent = event.get();

    FOR_EACH_CGEVENT_INTEGER_FIELD(STORE_INTEGER_FIELD_TO_EVENT);
    FOR_EACH_CGEVENT_DOUBLE_FIELD(STORE_DOUBLE_FIELD_TO_EVENT);

    if (dict[@"relativeTimeMS"])
        CGEventSetTimestamp(event.get(), referenceTimestamp + static_cast<CGEventTimestamp>(([dict[@"relativeTimeMS"] doubleValue] * NSEC_PER_MSEC)));

    if ([dict[@"kCGEventGestureIsPreflight"] boolValue]) {
        CGEventSetIntegerValueField(rawEvent, kCGEventGestureIsPreflight, 1);
        CGEventSetDoubleValueField(rawEvent, kCGEventGesturePreflightProgress, [dict[@"kCGEventGesturePreflightProgress"] doubleValue]);
    }

    if (dict[@"windowLocation"]) {
        CGPoint windowLocation = NSPointToCGPoint(NSPointFromString(dict[@"windowLocation"]));
        CGEventSetWindowLocation(rawEvent, windowLocation);

        NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowLocation.x, windowLocation.y, 1, 1)].origin;
        CGEventSetLocation(rawEvent, CGPointMake(screenPoint.x, NSScreen.screens.firstObject.frame.size.height - screenPoint.y));
    }

    if (dict[@"flags"])
        CGEventSetFlags(rawEvent, static_cast<CGEventFlags>([dict[@"flags"] unsignedLongLongValue]));

    CGEventSetIntegerValueField(rawEvent, kCGSEventWindowIDField, window.windowNumber);

    return event;
}

@end

@implementation EventStreamPlayer

const float eventDispatchTimerRate = 1. / 120.;

+ (void)playStream:(NSArray<NSDictionary *> *)eventDicts window:(NSWindow *)window completionHandler:(void(^)())completionHandler
{
    auto player = adoptNS([[EventStreamPlayer alloc] init]);

    player->_remainingEventDictionaries = adoptNS([eventDicts mutableCopy]);
    player->_window = window;

    if (completionHandler)
        player->_completionHandler = makeBlockPtr(completionHandler);

    player->_startTime = mach_absolute_time();

    [NSTimer scheduledTimerWithTimeInterval:eventDispatchTimerRate target:player.get() selector:@selector(playbackTimerFired:) userInfo:nil repeats:YES];
}

- (void)playbackTimerFired:(NSTimer *)timer
{
    auto removeList = adoptNS([[NSMutableArray alloc] init]);
    NSEvent *nsEvent = nil;
    for (id eventDict in _remainingEventDictionaries.get()) {
        auto event = [EventSerializer createEventForDictionary:eventDict inWindow:_window.get() relativeToTime:_startTime];
        if (CGEventGetTimestamp(event.get()) < mach_absolute_time()) {
            nsEvent = [NSEvent eventWithCGEvent:event.get()];
            [NSApp postEvent:nsEvent atStart:NO];
            [removeList addObject:eventDict];
        }
    }
    [_remainingEventDictionaries removeObjectsInArray:removeList.get()];

    if ([_remainingEventDictionaries count])
        return;

    NSEventType applicationDefinedEventType = NSEventTypeApplicationDefined;
    [NSApp postEvent:[NSEvent otherEventWithType:applicationDefinedEventType location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:0 context:0 subtype:0 data1:42 data2:0] atStart:NO];
    // Block until we send the last event we posted.
    while (true) {
        NSEvent *nextEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate dateWithTimeIntervalSinceNow:eventDispatchTimerRate] inMode:NSDefaultRunLoopMode dequeue:YES];
        if (nextEvent.type == applicationDefinedEventType && nextEvent.data1 == 42)
            break;
        if (nextEvent)
            [NSApp sendEvent:nextEvent];
    }

    if (_completionHandler)
        _completionHandler();

    [timer invalidate];
}

@end

#endif
