// Copyright 2013 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 <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>

#import <objc/runtime.h>

#import "flutter/common/settings.h"
#include "flutter/fml/synchronization/sync_switch.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
#import "flutter/shell/platform/darwin/common/framework/Source/FlutterBinaryMessengerRelay.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h"
#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"

FLUTTER_ASSERT_ARC

@interface FlutterEngineSpy : FlutterEngine
@property(nonatomic) BOOL ensureSemanticsEnabledCalled;
@end

@implementation FlutterEngineSpy

- (void)ensureSemanticsEnabled {
  _ensureSemanticsEnabledCalled = YES;
}

@end

@interface FlutterEngine () <FlutterTextInputDelegate>

@end

/// FlutterBinaryMessengerRelay used for testing that setting FlutterEngine.binaryMessenger to
/// the current instance doesn't trigger a use-after-free bug.
///
/// See: testSetBinaryMessengerToSameBinaryMessenger
@interface FakeBinaryMessengerRelay : FlutterBinaryMessengerRelay
@property(nonatomic, assign) BOOL failOnDealloc;
@end

@implementation FakeBinaryMessengerRelay
- (void)dealloc {
  if (_failOnDealloc) {
    XCTFail("FakeBinaryMessageRelay should not be deallocated");
  }
}
@end

@interface FlutterEngineTest : XCTestCase
@end

@implementation FlutterEngineTest

- (void)setUp {
}

- (void)tearDown {
}

- (void)testCreate {
  FlutterDartProject* project = [[FlutterDartProject alloc] init];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  XCTAssertNotNil(engine);
}

- (void)testInfoPlist {
  // Check the embedded Flutter.framework Info.plist, not the linked dylib.
  NSURL* flutterFrameworkURL =
      [NSBundle.mainBundle.privateFrameworksURL URLByAppendingPathComponent:@"Flutter.framework"];
  NSBundle* flutterBundle = [NSBundle bundleWithURL:flutterFrameworkURL];
  XCTAssertEqualObjects(flutterBundle.bundleIdentifier, @"io.flutter.flutter");

  NSDictionary<NSString*, id>* infoDictionary = flutterBundle.infoDictionary;

  // OS version can have one, two, or three digits: "8", "8.0", "8.0.0"
  NSError* regexError = NULL;
  NSRegularExpression* osVersionRegex =
      [NSRegularExpression regularExpressionWithPattern:@"((0|[1-9]\\d*)\\.)*(0|[1-9]\\d*)"
                                                options:NSRegularExpressionCaseInsensitive
                                                  error:&regexError];
  XCTAssertNil(regexError);

  // Smoke test the test regex.
  NSString* testString = @"9";
  NSUInteger versionMatches =
      [osVersionRegex numberOfMatchesInString:testString
                                      options:NSMatchingAnchored
                                        range:NSMakeRange(0, testString.length)];
  XCTAssertEqual(versionMatches, 1UL);
  testString = @"9.1";
  versionMatches = [osVersionRegex numberOfMatchesInString:testString
                                                   options:NSMatchingAnchored
                                                     range:NSMakeRange(0, testString.length)];
  XCTAssertEqual(versionMatches, 1UL);
  testString = @"9.0.1";
  versionMatches = [osVersionRegex numberOfMatchesInString:testString
                                                   options:NSMatchingAnchored
                                                     range:NSMakeRange(0, testString.length)];
  XCTAssertEqual(versionMatches, 1UL);
  testString = @".0.1";
  versionMatches = [osVersionRegex numberOfMatchesInString:testString
                                                   options:NSMatchingAnchored
                                                     range:NSMakeRange(0, testString.length)];
  XCTAssertEqual(versionMatches, 0UL);

  // Test Info.plist values.
  NSString* minimumOSVersion = infoDictionary[@"MinimumOSVersion"];
  versionMatches = [osVersionRegex numberOfMatchesInString:minimumOSVersion
                                                   options:NSMatchingAnchored
                                                     range:NSMakeRange(0, minimumOSVersion.length)];
  XCTAssertEqual(versionMatches, 1UL);

  // SHA length is 40.
  XCTAssertEqual(((NSString*)infoDictionary[@"FlutterEngine"]).length, 40UL);

  // {clang_version} placeholder is 15 characters. The clang string version
  // is longer than that, so check if the placeholder has been replaced, without
  // actually checking a literal string, which could be different on various machines.
  XCTAssertTrue(((NSString*)infoDictionary[@"ClangVersion"]).length > 15UL);
}

- (void)testDeallocated {
  __weak FlutterEngine* weakEngine = nil;
  @autoreleasepool {
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar"];
    weakEngine = engine;
    [engine run];
    XCTAssertNotNil(weakEngine);
  }
  XCTAssertNil(weakEngine);
}

- (void)testSendMessageBeforeRun {
  FlutterDartProject* project = [[FlutterDartProject alloc] init];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  XCTAssertNotNil(engine);
  XCTAssertThrows([engine.binaryMessenger
      sendOnChannel:@"foo"
            message:[@"bar" dataUsingEncoding:NSUTF8StringEncoding]
        binaryReply:nil]);
}

- (void)testSetMessageHandlerBeforeRun {
  FlutterDartProject* project = [[FlutterDartProject alloc] init];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  XCTAssertNotNil(engine);
  XCTAssertThrows([engine.binaryMessenger
      setMessageHandlerOnChannel:@"foo"
            binaryMessageHandler:^(NSData* _Nullable message, FlutterBinaryReply _Nonnull reply){

            }]);
}

- (void)testNilSetMessageHandlerBeforeRun {
  FlutterDartProject* project = [[FlutterDartProject alloc] init];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  XCTAssertNotNil(engine);
  XCTAssertNoThrow([engine.binaryMessenger setMessageHandlerOnChannel:@"foo"
                                                 binaryMessageHandler:nil]);
}

- (void)testNotifyPluginOfDealloc {
  id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
  OCMStub([plugin detachFromEngineForRegistrar:[OCMArg any]]);
  {
    FlutterDartProject* project = [[FlutterDartProject alloc] init];
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"engine" project:project];
    NSObject<FlutterPluginRegistrar>* registrar = [engine registrarForPlugin:@"plugin"];
    [registrar publish:plugin];
    engine = nil;
  }
  OCMVerify([plugin detachFromEngineForRegistrar:[OCMArg any]]);
}

- (void)testSetBinaryMessengerToSameBinaryMessenger {
  FakeBinaryMessengerRelay* fakeBinaryMessenger = [[FakeBinaryMessengerRelay alloc] init];

  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine setBinaryMessenger:fakeBinaryMessenger];

  // Verify that the setter doesn't free the old messenger before setting the new messenger.
  fakeBinaryMessenger.failOnDealloc = YES;
  [engine setBinaryMessenger:fakeBinaryMessenger];

  // Don't fail when ARC releases the binary messenger.
  fakeBinaryMessenger.failOnDealloc = NO;
}

- (void)testRunningInitialRouteSendsNavigationMessage {
  id mockBinaryMessenger = OCMClassMock([FlutterBinaryMessengerRelay class]);

  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine setBinaryMessenger:mockBinaryMessenger];

  // Run with an initial route.
  [engine runWithEntrypoint:FlutterDefaultDartEntrypoint initialRoute:@"test"];

  // Now check that an encoded method call has been made on the binary messenger to set the
  // initial route to "test".
  FlutterMethodCall* setInitialRouteMethodCall =
      [FlutterMethodCall methodCallWithMethodName:@"setInitialRoute" arguments:@"test"];
  NSData* encodedSetInitialRouteMethod =
      [[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:setInitialRouteMethodCall];
  OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/navigation"
                                       message:encodedSetInitialRouteMethod]);
}

- (void)testInitialRouteSettingsSendsNavigationMessage {
  id mockBinaryMessenger = OCMClassMock([FlutterBinaryMessengerRelay class]);

  auto settings = FLTDefaultSettingsForBundle();
  settings.route = "test";
  FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  [engine setBinaryMessenger:mockBinaryMessenger];
  [engine run];

  // Now check that an encoded method call has been made on the binary messenger to set the
  // initial route to "test".
  FlutterMethodCall* setInitialRouteMethodCall =
      [FlutterMethodCall methodCallWithMethodName:@"setInitialRoute" arguments:@"test"];
  NSData* encodedSetInitialRouteMethod =
      [[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:setInitialRouteMethodCall];
  OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/navigation"
                                       message:encodedSetInitialRouteMethod]);
}

- (void)testPlatformViewsControllerRenderingMetalBackend {
  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine run];
  flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI];

  XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kMetal);
}

- (void)testPlatformViewsControllerRenderingSoftware {
  auto settings = FLTDefaultSettingsForBundle();
  settings.enable_software_rendering = true;
  FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  [engine run];
  flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI];

  XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kSoftware);
}

- (void)testWaitForFirstFrameTimeout {
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar"];
  [engine run];
  XCTestExpectation* timeoutFirstFrame = [self expectationWithDescription:@"timeoutFirstFrame"];
  [engine waitForFirstFrame:0.1
                   callback:^(BOOL didTimeout) {
                     if (timeoutFirstFrame) {
                       [timeoutFirstFrame fulfill];
                     }
                   }];
  [self waitForExpectationsWithTimeout:5 handler:nil];
}

- (void)testSpawn {
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar"];
  [engine run];
  FlutterEngine* spawn = [engine spawnWithEntrypoint:nil
                                          libraryURI:nil
                                        initialRoute:nil
                                      entrypointArgs:nil];
  XCTAssertNotNil(spawn);
}

- (void)testDeallocNotification {
  XCTestExpectation* deallocNotification = [self expectationWithDescription:@"deallocNotification"];
  NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
  id<NSObject> observer;
  @autoreleasepool {
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar"];
    observer = [center addObserverForName:kFlutterEngineWillDealloc
                                   object:engine
                                    queue:[NSOperationQueue mainQueue]
                               usingBlock:^(NSNotification* note) {
                                 [deallocNotification fulfill];
                               }];
  }
  [self waitForExpectationsWithTimeout:1 handler:nil];
  [center removeObserver:observer];
}

- (void)testSetHandlerAfterRun {
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar"];
  XCTestExpectation* gotMessage = [self expectationWithDescription:@"gotMessage"];
  dispatch_async(dispatch_get_main_queue(), ^{
    NSObject<FlutterPluginRegistrar>* registrar = [engine registrarForPlugin:@"foo"];
    fml::AutoResetWaitableEvent latch;
    [engine run];
    flutter::Shell& shell = engine.shell;
    engine.shell.GetTaskRunners().GetUITaskRunner()->PostTask([&latch, &shell] {
      flutter::Engine::Delegate& delegate = shell;
      auto message = std::make_unique<flutter::PlatformMessage>("foo", nullptr);
      delegate.OnEngineHandlePlatformMessage(std::move(message));
      latch.Signal();
    });
    latch.Wait();
    [registrar.messenger setMessageHandlerOnChannel:@"foo"
                               binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) {
                                 [gotMessage fulfill];
                               }];
  });
  [self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testThreadPrioritySetCorrectly {
  XCTestExpectation* prioritiesSet = [self expectationWithDescription:@"prioritiesSet"];
  prioritiesSet.expectedFulfillmentCount = 3;

  IMP mockSetThreadPriority =
      imp_implementationWithBlock(^(NSThread* thread, double threadPriority) {
        if ([thread.name hasSuffix:@".ui"]) {
          XCTAssertEqual(threadPriority, 1.0);
          [prioritiesSet fulfill];
        } else if ([thread.name hasSuffix:@".raster"]) {
          XCTAssertEqual(threadPriority, 1.0);
          [prioritiesSet fulfill];
        } else if ([thread.name hasSuffix:@".io"]) {
          XCTAssertEqual(threadPriority, 0.5);
          [prioritiesSet fulfill];
        }
      });
  Method method = class_getInstanceMethod([NSThread class], @selector(setThreadPriority:));
  IMP originalSetThreadPriority = method_getImplementation(method);
  method_setImplementation(method, mockSetThreadPriority);

  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine run];
  [self waitForExpectationsWithTimeout:1 handler:nil];

  method_setImplementation(method, originalSetThreadPriority);
}

- (void)testCanEnableDisableEmbedderAPIThroughInfoPlist {
  {
    // Not enable embedder API by default
    auto settings = FLTDefaultSettingsForBundle();
    settings.enable_software_rendering = true;
    FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings];
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
    XCTAssertFalse(engine.enableEmbedderAPI);
  }
  {
    // Enable embedder api
    id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
    OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableIOSEmbedderAPI"])
        .andReturn(@"YES");
    auto settings = FLTDefaultSettingsForBundle();
    settings.enable_software_rendering = true;
    FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings];
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
    XCTAssertTrue(engine.enableEmbedderAPI);
  }
}

- (void)testFlutterTextInputViewDidResignFirstResponderWillCallTextInputClientConnectionClosed {
  id mockBinaryMessenger = OCMClassMock([FlutterBinaryMessengerRelay class]);
  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine setBinaryMessenger:mockBinaryMessenger];
  [engine runWithEntrypoint:FlutterDefaultDartEntrypoint initialRoute:@"test"];
  [engine flutterTextInputView:nil didResignFirstResponderWithTextInputClient:1];
  FlutterMethodCall* methodCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInputClient.onConnectionClosed"
                                        arguments:@[ @(1) ]];
  NSData* encodedMethodCall = [[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:methodCall];
  OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/textinput" message:encodedMethodCall]);
}

- (void)testFlutterEngineUpdatesDisplays {
  FlutterEngine* engine = [[FlutterEngine alloc] init];
  id mockEngine = OCMPartialMock(engine);

  [engine run];
  OCMVerify(times(1), [mockEngine updateDisplays]);
  engine.viewController = nil;
  OCMVerify(times(2), [mockEngine updateDisplays]);
}

- (void)testLifeCycleNotificationDidEnterBackground {
  FlutterDartProject* project = [[FlutterDartProject alloc] init];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  [engine run];
  NSNotification* sceneNotification =
      [NSNotification notificationWithName:UISceneDidEnterBackgroundNotification
                                    object:nil
                                  userInfo:nil];
  NSNotification* applicationNotification =
      [NSNotification notificationWithName:UIApplicationDidEnterBackgroundNotification
                                    object:nil
                                  userInfo:nil];
  id mockEngine = OCMPartialMock(engine);
  [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
  [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
#if APPLICATION_EXTENSION_API_ONLY
  OCMVerify(times(1), [mockEngine sceneDidEnterBackground:[OCMArg any]]);
#else
  OCMVerify(times(1), [mockEngine applicationDidEnterBackground:[OCMArg any]]);
#endif
  XCTAssertTrue(engine.isGpuDisabled);
  bool switch_value = false;
  [engine shell].GetIsGpuDisabledSyncSwitch()->Execute(
      fml::SyncSwitch::Handlers().SetIfTrue([&] { switch_value = true; }).SetIfFalse([&] {
        switch_value = false;
      }));
  XCTAssertTrue(switch_value);
}

- (void)testLifeCycleNotificationWillEnterForeground {
  FlutterDartProject* project = [[FlutterDartProject alloc] init];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
  [engine run];
  NSNotification* sceneNotification =
      [NSNotification notificationWithName:UISceneWillEnterForegroundNotification
                                    object:nil
                                  userInfo:nil];
  NSNotification* applicationNotification =
      [NSNotification notificationWithName:UIApplicationWillEnterForegroundNotification
                                    object:nil
                                  userInfo:nil];
  id mockEngine = OCMPartialMock(engine);
  [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
  [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
#if APPLICATION_EXTENSION_API_ONLY
  OCMVerify(times(1), [mockEngine sceneWillEnterForeground:[OCMArg any]]);
#else
  OCMVerify(times(1), [mockEngine applicationWillEnterForeground:[OCMArg any]]);
#endif
  XCTAssertFalse(engine.isGpuDisabled);
  bool switch_value = true;
  [engine shell].GetIsGpuDisabledSyncSwitch()->Execute(
      fml::SyncSwitch::Handlers().SetIfTrue([&] { switch_value = true; }).SetIfFalse([&] {
        switch_value = false;
      }));
  XCTAssertFalse(switch_value);
}

- (void)testSpawnsShareGpuContext {
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar"];
  [engine run];
  FlutterEngine* spawn = [engine spawnWithEntrypoint:nil
                                          libraryURI:nil
                                        initialRoute:nil
                                      entrypointArgs:nil];
  XCTAssertNotNil(spawn);
  XCTAssertTrue([engine iosPlatformView] != nullptr);
  XCTAssertTrue([spawn iosPlatformView] != nullptr);
  std::shared_ptr<flutter::IOSContext> engine_context = [engine iosPlatformView]->GetIosContext();
  std::shared_ptr<flutter::IOSContext> spawn_context = [spawn iosPlatformView]->GetIosContext();
  XCTAssertEqual(engine_context, spawn_context);
  // If this assert fails it means we may be using the software.  For software rendering, this is
  // expected to be nullptr.
  XCTAssertTrue(engine_context->GetMainContext() != nullptr);
  XCTAssertEqual(engine_context->GetMainContext(), spawn_context->GetMainContext());
}

- (void)testEnableSemanticsWhenFlutterViewAccessibilityDidCall {
  FlutterEngineSpy* engine = [[FlutterEngineSpy alloc] initWithName:@"foobar"];
  engine.ensureSemanticsEnabledCalled = NO;
  [engine flutterViewAccessibilityDidCall];
  XCTAssertTrue(engine.ensureSemanticsEnabledCalled);
}

@end
