/*
 * Copyright (C) 2012 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 "PlatformUtilities.h"
#import "PlatformWebView.h"
#import "WTFStringUtilities.h"

#import <WebKit/WebViewPrivate.h>
#import <WebKit/WebURLsWithTitles.h>
#import <WebKit/DOM.h>
#import <Carbon/Carbon.h>
#import <wtf/RetainPtr.h>
#import <wtf/mac/AppKitCompatibilityDeclarations.h>


@interface ContextMenuCanCopyURLDelegate : NSObject <WebFrameLoadDelegate> {
}
@end

static bool didFinishLoad;

@implementation ContextMenuCanCopyURLDelegate

- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
    didFinishLoad = true;
}

@end

namespace TestWebKitAPI {

static void contextMenuCopyLink(WebView* webView, int itemIndex)
{
    [[[[webView mainFrame] frameView] documentView] layout];
    
    DOMDocument *document = [[webView mainFrame] DOMDocument];
    DOMElement *documentElement = [document documentElement];
    DOMHTMLAnchorElement *anchor = (DOMHTMLAnchorElement *)[[documentElement querySelectorAll:@"a"] item:itemIndex];

    NSWindow *window = [webView window];
    NSEvent *event = [NSEvent mouseEventWithType:NSEventTypeRightMouseDown
                                        location:NSMakePoint(anchor.offsetLeft + anchor.offsetWidth / 2, window.frame.size.height - (anchor.offsetTop + anchor.offsetHeight / 2))
                                   modifierFlags:0
                                       timestamp:GetCurrentEventTime()
                                    windowNumber:[window windowNumber]
                                         context:[NSGraphicsContext currentContext] 
                                     eventNumber:0
                                      clickCount:0
                                        pressure:0.0];

    NSView *subView = [webView hitTest:[event locationInWindow]];
    if (!subView)
        return;

    NSMenu* menu = [subView menuForEvent:event];
    for (int i = 0; i < [menu numberOfItems]; ++i) {
        NSMenuItem* menuItem = [menu itemAtIndex:i];
        if ([menuItem tag] != WebMenuItemTagCopyLinkToClipboard)
            continue;
            
        [menu performActionForItemAtIndex:i];
    }
}

TEST(WebKitLegacy, ContextMenuCanCopyURL)
{
    RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0,0,800,600) frameName:nil groupName:nil]);
    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:NSMakeRect(100, 100, 800, 600) styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    RetainPtr<ContextMenuCanCopyURLDelegate> delegate = adoptNS([[ContextMenuCanCopyURLDelegate alloc] init]);

    [window.get().contentView addSubview:webView.get()];
    webView.get().frameLoadDelegate = delegate.get();

    [webView.get().mainFrame loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"ContextMenuCanCopyURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
    
    Util::run(&didFinishLoad);

    contextMenuCopyLink(webView.get(), 0);
    
    NSURL *url = [NSURL URLFromPasteboard:[NSPasteboard generalPasteboard]];
    EXPECT_EQ(String("http://www.webkit.org/"), String([url absoluteString]));

    contextMenuCopyLink(webView.get(), 1);
    
    NSArray * urls = [WebURLsWithTitles URLsFromPasteboard: [NSPasteboard generalPasteboard]];
    NSArray * titles = [WebURLsWithTitles titlesFromPasteboard: [NSPasteboard generalPasteboard]];
    EXPECT_WK_STREQ(@"http://xn--ls8h.la/", [[urls objectAtIndex:0] absoluteString]);
    EXPECT_WK_STREQ(@"http://💩.la", [titles objectAtIndex:0]);

    contextMenuCopyLink(webView.get(), 2);

    urls = [WebURLsWithTitles URLsFromPasteboard:[NSPasteboard generalPasteboard]];
    titles = [WebURLsWithTitles titlesFromPasteboard:[NSPasteboard generalPasteboard]];
    EXPECT_WK_STREQ(@"https://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", [[urls objectAtIndex:0] absoluteString]);
    EXPECT_WK_STREQ(@"big_buck_bunny.mp4", [titles objectAtIndex:0]);

    contextMenuCopyLink(webView.get(), 3);

    urls = [WebURLsWithTitles URLsFromPasteboard:[NSPasteboard generalPasteboard]];
    titles = [WebURLsWithTitles titlesFromPasteboard:[NSPasteboard generalPasteboard]];
    EXPECT_WK_STREQ(@"https://en.wikipedia.org/wiki/Gary_Busey/media/File:Texas_Wheelers_cast.JPG", [[urls objectAtIndex:0] absoluteString]);
    EXPECT_WK_STREQ(@"File:Texas_Wheelers_cast.JPG", [titles objectAtIndex:0]);
}

} // namespace TestWebKitAPI
