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

#if PLATFORM(COCOA)

#import "Color.h"
#import "WebCoreCALayerExtras.h"
#import <CoreText/CoreText.h>
#import <wtf/WeakObjCPtr.h>

#if PLATFORM(IOS_FAMILY)
#import <pal/ios/UIKitSoftLink.h>
#endif

static void *boundsObservationContext = &boundsObservationContext;

@interface WebViewVisualIdentificationOverlay () <CALayerDelegate>
@end

const void* const webViewVisualIdentificationOverlayKey = &webViewVisualIdentificationOverlayKey;

@implementation WebViewVisualIdentificationOverlay {
    RetainPtr<PlatformView> _view;

    RetainPtr<CALayer> _layer;
    RetainPtr<NSString> _kind;
}

+ (BOOL)shouldIdentifyWebViews
{
    static std::optional<BOOL> shouldIdentifyWebViews;
    if (!shouldIdentifyWebViews)
        shouldIdentifyWebViews = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitDebugIdentifyWebViews"];
    return *shouldIdentifyWebViews;
}

+ (void)installForWebViewIfNeeded:(PlatformView *)view kind:(NSString *)kind deprecated:(BOOL)isDeprecated
{
    if (![self shouldIdentifyWebViews])
        return;
    auto overlay = adoptNS([[WebViewVisualIdentificationOverlay alloc] initWithWebView:view kind:kind deprecated:isDeprecated]);
    objc_setAssociatedObject(self, webViewVisualIdentificationOverlayKey, overlay.get(), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (instancetype)initWithWebView:(PlatformView *)webView kind:(NSString *)kind deprecated:(BOOL)isDeprecated
{
    self = [super init];
    if (!self)
        return nil;

    _kind = kind;

#if USE(APPKIT)
    _view = adoptNS([[NSView alloc] initWithFrame:webView.bounds]);
    [_view setWantsLayer:YES];
    [_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
#else
    _view = adoptNS([PAL::allocUIViewInstance() initWithFrame:webView.bounds]);
    [_view setUserInteractionEnabled:NO];
    [_view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
#endif
    [webView addSubview:_view.get()];

#if PLATFORM(MACCATALYST)
    _kind = [_kind stringByAppendingString:@" (macCatalyst)"];
#endif

    _layer = adoptNS([[CATiledLayer alloc] init]);
    [_layer setName:@"WebViewVisualIdentificationOverlay"];
    [_layer setFrame:CGRectMake(0, 0, [_view bounds].size.width, [_view bounds].size.height)];
    auto viewColor = isDeprecated ? WebCore::Color::red.colorWithAlphaByte(50) : WebCore::Color::blue.colorWithAlphaByte(32);
    [_layer setBackgroundColor:cachedCGColor(viewColor)];
    [_layer setZPosition:999];
    [_layer setDelegate:self];
    [_layer web_disableAllActions];
    [[_view layer] addSublayer:_layer.get()];

    [[_view layer] addObserver:self forKeyPath:@"bounds" options:0 context:boundsObservationContext];

    return self;
}

- (void)dealloc
{
    [[_view layer] removeObserver:self forKeyPath:@"bounds" context:boundsObservationContext];

    [super dealloc];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context
{
    UNUSED_PARAM(keyPath);
    UNUSED_PARAM(object);
    UNUSED_PARAM(change);
    if (context == boundsObservationContext) {
        [_layer setFrame:CGRectMake(0, 0, [_view bounds].size.width, [_view bounds].size.height)];
        [_layer setNeedsDisplay];
    }
}

static RetainPtr<CTFontRef> createIdentificationFont()
{
    auto matrix = CGAffineTransformIdentity;
    return adoptCF(CTFontCreateWithName(CFSTR("Helvetica"), 20, &matrix));
}

constexpr CGFloat horizontalMargin = 15;
constexpr CGFloat verticalMargin = 5;

static void drawPattern(void *overlayPtr, CGContextRef ctx)
{
    WebViewVisualIdentificationOverlay *overlay = (WebViewVisualIdentificationOverlay *)overlayPtr;

    auto attributes = @{
        (id)kCTFontAttributeName : (id)createIdentificationFont().get(),
        (id)kCTForegroundColorFromContextAttributeName : @YES
    };
    auto attributedString = adoptCF(CFAttributedStringCreate(kCFAllocatorDefault, (__bridge CFStringRef)overlay->_kind.get(), (__bridge CFDictionaryRef)attributes));
    auto line = adoptCF(CTLineCreateWithAttributedString(attributedString.get()));

    CGSize textSize = [overlay->_kind sizeWithAttributes:attributes];

#if PLATFORM(IOS_FAMILY)
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -(textSize.height + verticalMargin) * 2);
#endif

    CGContextSetTextDrawingMode(ctx, kCGTextFill);

    CGContextSetTextPosition(ctx, 0, 0);
    CGContextSetFillColorWithColor(ctx, cachedCGColor(WebCore::Color::black));
    CTLineDraw(line.get(), ctx);

    CGContextSetTextPosition(ctx, 0, textSize.height + 5);
    CGContextSetFillColorWithColor(ctx, cachedCGColor(WebCore::Color::white));
    CTLineDraw(line.get(), ctx);
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    CGPatternCallbacks callbacks = { 0, &drawPattern, nullptr };
    auto patternSpace = adoptCF(CGColorSpaceCreatePattern(nullptr));
    CGContextSetFillColorSpace(ctx, patternSpace.get());

    CGSize textSize = [_kind sizeWithAttributes:@{ (id)kCTFontAttributeName : (id)createIdentificationFont().get() }];
    CGSize patternSize = CGSizeMake(textSize.width + horizontalMargin, (textSize.height + verticalMargin) * 2);
    auto pattern = adoptCF(CGPatternCreate(self, layer.bounds, CGAffineTransformMakeRotation(M_PI_4), patternSize.width, patternSize.height, kCGPatternTilingNoDistortion, true, &callbacks));
    CGFloat alpha = 0.5;
    CGContextSetFillPattern(ctx, pattern.get(), &alpha);

    CGContextFillRect(ctx, layer.bounds);
}

@end

#endif // PLATFORM(COCOA)
