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

#import "PlatformUtilities.h"
#import <WebKit/WKWebViewPrivateForTesting.h>

@implementation EditingTestHarness

- (instancetype)initWithWebView:(TestWKWebView *)webView
{
    if (self = [super init]) {
        _webView = webView;
        [_webView setUIDelegate:self];
        _editorStateHistory = adoptNS([[NSMutableArray alloc] init]);
    }
    return self;
}

- (void)dealloc
{
    if ([_webView UIDelegate] == self)
        [_webView setUIDelegate:nil];

    [super dealloc];
}

- (TestWKWebView *)webView
{
    return _webView.get();
}

- (NSDictionary *)latestEditorState
{
    return self.editorStateHistory.lastObject;
}

- (NSArray<NSDictionary *> *)editorStateHistory
{
    return _editorStateHistory.get();
}

- (void)insertParagraph
{
    [self insertParagraphAndExpectEditorStateWith:nil];
}

- (void)insertText:(NSString *)text
{
    [self insertText:text andExpectEditorStateWith:nil];
}

- (void)insertHTML:(NSString *)html
{
    [self insertHTML:html andExpectEditorStateWith:nil];
}

- (void)selectAll
{
    [self selectAllAndExpectEditorStateWith:nil];
}

- (void)deleteBackwards
{
    [self deleteBackwardAndExpectEditorStateWith:nil];
}

- (void)moveBackward
{
    [self moveBackwardAndExpectEditorStateWith:nil];
}

- (void)moveForward
{
    [self moveForwardAndExpectEditorStateWith:nil];
}

- (void)insertText:(NSString *)text andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"InsertText" argument:text expectEntries:entries];
}

- (void)insertHTML:(NSString *)html andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"InsertHTML" argument:html expectEntries:entries];
}

- (void)selectAllAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"SelectAll" argument:nil expectEntries:entries];
}

- (void)moveBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"MoveBackward" argument:nil expectEntries:entries];
}

- (void)moveWordBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"MoveWordBackward" argument:nil expectEntries:entries];
}

- (void)moveForwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"MoveForward" argument:nil expectEntries:entries];
}

- (void)toggleBold
{
    [self _execCommand:@"ToggleBold" argument:nil expectEntries:nil];
}

- (void)toggleItalic
{
    [self _execCommand:@"ToggleItalic" argument:nil expectEntries:nil];
}

- (void)toggleUnderline
{
    [self _execCommand:@"ToggleUnderline" argument:nil expectEntries:nil];
}

- (void)setForegroundColor:(NSString *)colorAsString
{
    [self _execCommand:@"ForeColor" argument:colorAsString expectEntries:nil];
}

- (void)alignJustifiedAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"AlignJustified" argument:nil expectEntries:entries];
}

- (void)alignLeftAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"AlignLeft" argument:nil expectEntries:entries];
}

- (void)alignCenterAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"AlignCenter" argument:nil expectEntries:entries];
}

- (void)alignRightAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"AlignRight" argument:nil expectEntries:entries];
}

- (void)insertParagraphAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"InsertParagraph" argument:nil expectEntries:entries];
}

- (void)deleteBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
    [self _execCommand:@"DeleteBackward" argument:nil expectEntries:entries];
}

- (void)_execCommand:(NSString *)command argument:(NSString *)argument expectEntries:(NSDictionary<NSString *, id> *)entries
{
    __block BOOL result = false;
    __block bool done = false;
    [_webView _executeEditCommand:command argument:argument completion:^(BOOL success) {
        result = success;
        done = true;
    }];
    TestWebKitAPI::Util::run(&done);

    EXPECT_TRUE(result);
    if (!result)
        NSLog(@"Failed to execute editing command: ('%@', '%@')", command, argument ?: @"");

    const NSTimeInterval loggingTimeout = 3;
    auto startTime = retainPtr([NSDate date]);
    BOOL hasLoggedWarning = NO;
    BOOL containsEntries;
    do {
        [_webView waitForNextPresentationUpdate];
        containsEntries = [self latestEditorStateContains:entries];
        if (!hasLoggedWarning && [[NSDate date] timeIntervalSinceDate:startTime.get()] > loggingTimeout) {
            NSLog(@"Expected %@ to contain %@", self.latestEditorState, entries);
            hasLoggedWarning = YES;
        }
    } while (!containsEntries);
}

- (BOOL)latestEditorStateContains:(NSDictionary<NSString *, id> *)entries
{
    NSDictionary *latestEditorState = self.latestEditorState;
    for (NSString *key in entries) {
        if (![latestEditorState[key] isEqual:entries[key]])
            return NO;
    }
    return latestEditorState.count || !entries.count;
}

#pragma mark - WKUIDelegatePrivate

- (void)_webView:(WKWebView *)webView editorStateDidChange:(NSDictionary *)editorState
{
    if (![editorState[@"post-layout-data"] boolValue])
        return;

    if (![self.latestEditorState isEqualToDictionary:editorState])
        [_editorStateHistory addObject:editorState];
}

@end
