// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "IntegrationTestPlugin.h"

@import UIKit;

static NSString *const kIntegrationTestPluginChannel = @"plugins.flutter.io/integration_test";
static NSString *const kMethodTestFinished = @"allTestsFinished";
static NSString *const kMethodScreenshot = @"captureScreenshot";
static NSString *const kMethodConvertSurfaceToImage = @"convertFlutterSurfaceToImage";
static NSString *const kMethodRevertImage = @"revertFlutterImage";

@interface IntegrationTestPlugin ()

@property(nonatomic, readwrite) NSDictionary<NSString *, NSString *> *testResults;

- (instancetype)init NS_DESIGNATED_INITIALIZER;

@end

@implementation IntegrationTestPlugin {
  NSDictionary<NSString *, NSString *> *_testResults;
  NSMutableDictionary<NSString *, UIImage *> *_capturedScreenshotsByName;
}

+ (IntegrationTestPlugin *)instance {
  static dispatch_once_t onceToken;
  static IntegrationTestPlugin *sInstance;
  dispatch_once(&onceToken, ^{
    sInstance = [[IntegrationTestPlugin alloc] initForRegistration];
  });
  return sInstance;
}

- (instancetype)initForRegistration {
  return [self init];
}

- (instancetype)init {
  self = [super init];
  _capturedScreenshotsByName = [NSMutableDictionary new];
  return self;
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
  // No initialization happens here because of the way XCTest loads the testing
  // bundles.  Setup on static variables can be disregarded when a new static
  // instance of IntegrationTestPlugin is allocated when the bundle is reloaded.
  // See also: https://github.com/flutter/plugins/pull/2465
}

- (void)setupChannels:(id<FlutterBinaryMessenger>)binaryMessenger {
  FlutterMethodChannel *channel =
  [FlutterMethodChannel methodChannelWithName:kIntegrationTestPluginChannel
                              binaryMessenger:binaryMessenger];
  [channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
    [self handleMethodCall:call result:result];
  }];
}

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
  if ([call.method isEqualToString:kMethodTestFinished]) {
    self.testResults = call.arguments[@"results"];
    result(nil);
  } else if ([call.method isEqualToString:kMethodScreenshot]) {
    // If running as a native Xcode test, attach to test.
    UIImage *screenshot = [self capturePngScreenshot];
    NSString *name = call.arguments[@"name"];
    _capturedScreenshotsByName[name] = screenshot;

    // Also pass back along the channel for the driver to handle.
    NSData *pngData = UIImagePNGRepresentation(screenshot);
    result([FlutterStandardTypedData typedDataWithBytes:pngData]);
  } else if ([call.method isEqualToString:kMethodConvertSurfaceToImage]
             || [call.method isEqualToString:kMethodRevertImage]) {
    // Android only, no-op on iOS.
    result(nil);
  } else {
    result(FlutterMethodNotImplemented);
  }
}

- (UIImage *)capturePngScreenshot {
  UIWindow *window = [UIApplication.sharedApplication.windows
                      filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"keyWindow = YES"]].firstObject;
  CGRect screenshotBounds = window.bounds;
  UIImage *image;

  if (@available(iOS 10, *)) {
    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithBounds:screenshotBounds];

    image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
      [window drawViewHierarchyInRect:screenshotBounds afterScreenUpdates:YES];
    }];
  } else {
    UIGraphicsBeginImageContextWithOptions(screenshotBounds.size, NO, UIScreen.mainScreen.scale);
    [window drawViewHierarchyInRect:screenshotBounds afterScreenUpdates:YES];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
  }

  return image;
}

@end
