// 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 "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#include "gtest/gtest.h"

#include <functional>
#include <thread>

#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/shell/platform/common/accessibility_bridge.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngineTestUtils.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/embedder_engine.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/testing/test_dart_native_resolver.h"

// CREATE_NATIVE_ENTRY and MOCK_ENGINE_PROC are leaky by design
// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)

@interface FlutterEngine (Test)
/**
 * The FlutterCompositor object currently in use by the FlutterEngine.
 *
 * May be nil if the compositor has not been initialized yet.
 */
@property(nonatomic, readonly, nullable) flutter::FlutterCompositor* macOSCompositor;
@end

@interface TestPlatformViewFactory : NSObject <FlutterPlatformViewFactory>
@end

@implementation TestPlatformViewFactory
- (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable id)args {
  return viewId == 42 ? [[NSView alloc] init] : nil;
}

@end

namespace flutter::testing {

TEST_F(FlutterEngineTest, CanLaunch) {
  FlutterEngine* engine = GetFlutterEngine();
  EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
  EXPECT_TRUE(engine.running);
}

TEST_F(FlutterEngineTest, HasNonNullExecutableName) {
  FlutterEngine* engine = GetFlutterEngine();
  std::string executable_name = [[engine executableName] UTF8String];
  ASSERT_FALSE(executable_name.empty());

  // Block until notified by the Dart test of the value of Platform.executable.
  fml::AutoResetWaitableEvent latch;
  AddNativeCallback("NotifyStringValue", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
                      const auto dart_string = tonic::DartConverter<std::string>::FromDart(
                          Dart_GetNativeArgument(args, 0));
                      EXPECT_EQ(executable_name, dart_string);
                      latch.Signal();
                    }));

  // Launch the test entrypoint.
  EXPECT_TRUE([engine runWithEntrypoint:@"executableNameNotNull"]);

  latch.Wait();
}

#ifndef FLUTTER_RELEASE
TEST_F(FlutterEngineTest, Switches) {
  setenv("FLUTTER_ENGINE_SWITCHES", "2", 1);
  setenv("FLUTTER_ENGINE_SWITCH_1", "abc", 1);
  setenv("FLUTTER_ENGINE_SWITCH_2", "foo=\"bar, baz\"", 1);

  FlutterEngine* engine = GetFlutterEngine();
  std::vector<std::string> switches = engine.switches;
  ASSERT_EQ(switches.size(), 2UL);
  EXPECT_EQ(switches[0], "--abc");
  EXPECT_EQ(switches[1], "--foo=\"bar, baz\"");

  unsetenv("FLUTTER_ENGINE_SWITCHES");
  unsetenv("FLUTTER_ENGINE_SWITCH_1");
  unsetenv("FLUTTER_ENGINE_SWITCH_2");
}
#endif  // !FLUTTER_RELEASE

TEST_F(FlutterEngineTest, MessengerSend) {
  FlutterEngine* engine = GetFlutterEngine();
  EXPECT_TRUE([engine runWithEntrypoint:@"main"]);

  NSData* test_message = [@"a message" dataUsingEncoding:NSUTF8StringEncoding];
  bool called = false;

  engine.embedderAPI.SendPlatformMessage = MOCK_ENGINE_PROC(
      SendPlatformMessage, ([&called, test_message](auto engine, auto message) {
        called = true;
        EXPECT_STREQ(message->channel, "test");
        EXPECT_EQ(memcmp(message->message, test_message.bytes, message->message_size), 0);
        return kSuccess;
      }));

  [engine.binaryMessenger sendOnChannel:@"test" message:test_message];
  EXPECT_TRUE(called);
}

TEST_F(FlutterEngineTest, CanLogToStdout) {
  // Block until completion of print statement.
  fml::AutoResetWaitableEvent latch;
  AddNativeCallback("SignalNativeTest",
                    CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { latch.Signal(); }));

  // Replace stdout stream buffer with our own.
  std::stringstream buffer;
  std::streambuf* old_buffer = std::cout.rdbuf();
  std::cout.rdbuf(buffer.rdbuf());

  // Launch the test entrypoint.
  FlutterEngine* engine = GetFlutterEngine();
  EXPECT_TRUE([engine runWithEntrypoint:@"canLogToStdout"]);
  EXPECT_TRUE(engine.running);

  latch.Wait();

  // Restore old stdout stream buffer.
  std::cout.rdbuf(old_buffer);

  // Verify hello world was written to stdout.
  std::string logs = buffer.str();
  EXPECT_TRUE(logs.find("Hello logging") != std::string::npos);
}

TEST_F(FlutterEngineTest, BackgroundIsBlack) {
  FlutterEngine* engine = GetFlutterEngine();

  // Latch to ensure the entire layer tree has been generated and presented.
  fml::AutoResetWaitableEvent latch;
  AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
                      CALayer* rootLayer = engine.viewController.flutterView.layer;
                      EXPECT_TRUE(rootLayer.backgroundColor != nil);
                      if (rootLayer.backgroundColor != nil) {
                        NSColor* actualBackgroundColor =
                            [NSColor colorWithCGColor:rootLayer.backgroundColor];
                        EXPECT_EQ(actualBackgroundColor, [NSColor blackColor]);
                      }
                      latch.Signal();
                    }));

  // Launch the test entrypoint.
  EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]);
  EXPECT_TRUE(engine.running);

  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController loadView];
  viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);

  latch.Wait();
}

TEST_F(FlutterEngineTest, CanOverrideBackgroundColor) {
  FlutterEngine* engine = GetFlutterEngine();

  // Latch to ensure the entire layer tree has been generated and presented.
  fml::AutoResetWaitableEvent latch;
  AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
                      CALayer* rootLayer = engine.viewController.flutterView.layer;
                      EXPECT_TRUE(rootLayer.backgroundColor != nil);
                      if (rootLayer.backgroundColor != nil) {
                        NSColor* actualBackgroundColor =
                            [NSColor colorWithCGColor:rootLayer.backgroundColor];
                        EXPECT_EQ(actualBackgroundColor, [NSColor whiteColor]);
                      }
                      latch.Signal();
                    }));

  // Launch the test entrypoint.
  EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]);
  EXPECT_TRUE(engine.running);

  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController loadView];
  viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
  viewController.flutterView.backgroundColor = [NSColor whiteColor];

  latch.Wait();
}

TEST_F(FlutterEngineTest, CanToggleAccessibility) {
  FlutterEngine* engine = GetFlutterEngine();
  // Capture the update callbacks before the embedder API initializes.
  auto original_init = engine.embedderAPI.Initialize;
  std::function<void(const FlutterSemanticsUpdate2*, void*)> update_semantics_callback;
  engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
      Initialize, ([&update_semantics_callback, &original_init](
                       size_t version, const FlutterRendererConfig* config,
                       const FlutterProjectArgs* args, void* user_data, auto engine_out) {
        update_semantics_callback = args->update_semantics_callback2;
        return original_init(version, config, args, user_data, engine_out);
      }));
  EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
  // Set up view controller.
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController loadView];
  // Enable the semantics.
  bool enabled_called = false;
  engine.embedderAPI.UpdateSemanticsEnabled =
      MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
                         enabled_called = enabled;
                         return kSuccess;
                       }));
  engine.semanticsEnabled = YES;
  EXPECT_TRUE(enabled_called);
  // Send flutter semantics updates.
  FlutterSemanticsNode2 root;
  root.id = 0;
  root.flags = static_cast<FlutterSemanticsFlag>(0);
  root.actions = static_cast<FlutterSemanticsAction>(0);
  root.text_selection_base = -1;
  root.text_selection_extent = -1;
  root.label = "root";
  root.hint = "";
  root.value = "";
  root.increased_value = "";
  root.decreased_value = "";
  root.tooltip = "";
  root.child_count = 1;
  int32_t children[] = {1};
  root.children_in_traversal_order = children;
  root.custom_accessibility_actions_count = 0;

  FlutterSemanticsNode2 child1;
  child1.id = 1;
  child1.flags = static_cast<FlutterSemanticsFlag>(0);
  child1.actions = static_cast<FlutterSemanticsAction>(0);
  child1.text_selection_base = -1;
  child1.text_selection_extent = -1;
  child1.label = "child 1";
  child1.hint = "";
  child1.value = "";
  child1.increased_value = "";
  child1.decreased_value = "";
  child1.tooltip = "";
  child1.child_count = 0;
  child1.custom_accessibility_actions_count = 0;

  FlutterSemanticsUpdate2 update;
  update.node_count = 2;
  FlutterSemanticsNode2* nodes[] = {&root, &child1};
  update.nodes = nodes;
  update.custom_action_count = 0;
  update_semantics_callback(&update, (__bridge void*)engine);

  // Verify the accessibility tree is attached to the flutter view.
  EXPECT_EQ([engine.viewController.flutterView.accessibilityChildren count], 1u);
  NSAccessibilityElement* native_root = engine.viewController.flutterView.accessibilityChildren[0];
  std::string root_label = [native_root.accessibilityLabel UTF8String];
  EXPECT_TRUE(root_label == "root");
  EXPECT_EQ(native_root.accessibilityRole, NSAccessibilityGroupRole);
  EXPECT_EQ([native_root.accessibilityChildren count], 1u);
  NSAccessibilityElement* native_child1 = native_root.accessibilityChildren[0];
  std::string child1_value = [native_child1.accessibilityValue UTF8String];
  EXPECT_TRUE(child1_value == "child 1");
  EXPECT_EQ(native_child1.accessibilityRole, NSAccessibilityStaticTextRole);
  EXPECT_EQ([native_child1.accessibilityChildren count], 0u);
  // Disable the semantics.
  bool semanticsEnabled = true;
  engine.embedderAPI.UpdateSemanticsEnabled =
      MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&semanticsEnabled](auto engine, bool enabled) {
                         semanticsEnabled = enabled;
                         return kSuccess;
                       }));
  engine.semanticsEnabled = NO;
  EXPECT_FALSE(semanticsEnabled);
  // Verify the accessibility tree is removed from the view.
  EXPECT_EQ([engine.viewController.flutterView.accessibilityChildren count], 0u);

  [engine setViewController:nil];
}

TEST_F(FlutterEngineTest, CanToggleAccessibilityWhenHeadless) {
  FlutterEngine* engine = GetFlutterEngine();
  // Capture the update callbacks before the embedder API initializes.
  auto original_init = engine.embedderAPI.Initialize;
  std::function<void(const FlutterSemanticsUpdate2*, void*)> update_semantics_callback;
  engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
      Initialize, ([&update_semantics_callback, &original_init](
                       size_t version, const FlutterRendererConfig* config,
                       const FlutterProjectArgs* args, void* user_data, auto engine_out) {
        update_semantics_callback = args->update_semantics_callback2;
        return original_init(version, config, args, user_data, engine_out);
      }));
  EXPECT_TRUE([engine runWithEntrypoint:@"main"]);

  // Enable the semantics without attaching a view controller.
  bool enabled_called = false;
  engine.embedderAPI.UpdateSemanticsEnabled =
      MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
                         enabled_called = enabled;
                         return kSuccess;
                       }));
  engine.semanticsEnabled = YES;
  EXPECT_TRUE(enabled_called);
  // Send flutter semantics updates.
  FlutterSemanticsNode2 root;
  root.id = 0;
  root.flags = static_cast<FlutterSemanticsFlag>(0);
  root.actions = static_cast<FlutterSemanticsAction>(0);
  root.text_selection_base = -1;
  root.text_selection_extent = -1;
  root.label = "root";
  root.hint = "";
  root.value = "";
  root.increased_value = "";
  root.decreased_value = "";
  root.tooltip = "";
  root.child_count = 1;
  int32_t children[] = {1};
  root.children_in_traversal_order = children;
  root.custom_accessibility_actions_count = 0;

  FlutterSemanticsNode2 child1;
  child1.id = 1;
  child1.flags = static_cast<FlutterSemanticsFlag>(0);
  child1.actions = static_cast<FlutterSemanticsAction>(0);
  child1.text_selection_base = -1;
  child1.text_selection_extent = -1;
  child1.label = "child 1";
  child1.hint = "";
  child1.value = "";
  child1.increased_value = "";
  child1.decreased_value = "";
  child1.tooltip = "";
  child1.child_count = 0;
  child1.custom_accessibility_actions_count = 0;

  FlutterSemanticsUpdate2 update;
  update.node_count = 2;
  FlutterSemanticsNode2* nodes[] = {&root, &child1};
  update.nodes = nodes;
  update.custom_action_count = 0;
  // This call updates semantics for the default view, which does not exist,
  // and therefore this call is invalid. But the engine should not crash.
  update_semantics_callback(&update, (__bridge void*)engine);

  // No crashes.
  EXPECT_EQ(engine.viewController, nil);

  // Disable the semantics.
  bool semanticsEnabled = true;
  engine.embedderAPI.UpdateSemanticsEnabled =
      MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&semanticsEnabled](auto engine, bool enabled) {
                         semanticsEnabled = enabled;
                         return kSuccess;
                       }));
  engine.semanticsEnabled = NO;
  EXPECT_FALSE(semanticsEnabled);
  // Still no crashes
  EXPECT_EQ(engine.viewController, nil);
}

TEST_F(FlutterEngineTest, ProducesAccessibilityTreeWhenAddingViews) {
  FlutterEngine* engine = GetFlutterEngine();
  EXPECT_TRUE([engine runWithEntrypoint:@"main"]);

  // Enable the semantics without attaching a view controller.
  bool enabled_called = false;
  engine.embedderAPI.UpdateSemanticsEnabled =
      MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
                         enabled_called = enabled;
                         return kSuccess;
                       }));
  engine.semanticsEnabled = YES;
  EXPECT_TRUE(enabled_called);

  EXPECT_EQ(engine.viewController, nil);

  // Assign the view controller after enabling semantics
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  engine.viewController = viewController;

  EXPECT_NE(viewController.accessibilityBridge.lock(), nullptr);
}

TEST_F(FlutterEngineTest, NativeCallbacks) {
  fml::AutoResetWaitableEvent latch;
  bool latch_called = false;
  AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
                      latch_called = true;
                      latch.Signal();
                    }));

  FlutterEngine* engine = GetFlutterEngine();
  EXPECT_TRUE([engine runWithEntrypoint:@"nativeCallback"]);
  EXPECT_TRUE(engine.running);

  latch.Wait();
  ASSERT_TRUE(latch_called);
}

TEST_F(FlutterEngineTest, Compositor) {
  NSString* fixtures = @(flutter::testing::GetFixturesPath());
  FlutterDartProject* project = [[FlutterDartProject alloc]
      initWithAssetsPath:fixtures
             ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];

  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController loadView];
  viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);

  EXPECT_TRUE([engine runWithEntrypoint:@"canCompositePlatformViews"]);

  [engine.platformViewController registerViewFactory:[[TestPlatformViewFactory alloc] init]
                                              withId:@"factory_id"];
  [engine.platformViewController
      handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create"
                                                         arguments:@{
                                                           @"id" : @(42),
                                                           @"viewType" : @"factory_id",
                                                         }]
                result:^(id result){
                }];

  [viewController.flutterView.threadSynchronizer blockUntilFrameAvailable];

  CALayer* rootLayer = viewController.flutterView.layer;

  // There are two layers with Flutter contents and one view
  EXPECT_EQ(rootLayer.sublayers.count, 2u);
  EXPECT_EQ(viewController.flutterView.subviews.count, 1u);

  // TODO(gw280): add support for screenshot tests in this test harness

  [engine shutDownEngine];
}  // namespace flutter::testing

TEST_F(FlutterEngineTest, DartEntrypointArguments) {
  NSString* fixtures = @(flutter::testing::GetFixturesPath());
  FlutterDartProject* project = [[FlutterDartProject alloc]
      initWithAssetsPath:fixtures
             ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];

  project.dartEntrypointArguments = @[ @"arg1", @"arg2" ];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];

  bool called = false;
  auto original_init = engine.embedderAPI.Initialize;
  engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
      Initialize, ([&called, &original_init](size_t version, const FlutterRendererConfig* config,
                                             const FlutterProjectArgs* args, void* user_data,
                                             FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
        called = true;
        EXPECT_EQ(args->dart_entrypoint_argc, 2);
        NSString* arg1 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[0]
                                                  encoding:NSUTF8StringEncoding];
        NSString* arg2 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[1]
                                                  encoding:NSUTF8StringEncoding];

        EXPECT_TRUE([arg1 isEqualToString:@"arg1"]);
        EXPECT_TRUE([arg2 isEqualToString:@"arg2"]);

        return original_init(version, config, args, user_data, engine_out);
      }));

  EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
  EXPECT_TRUE(called);
}

// If a channel overrides a previous channel with the same name, cleaning
// the previous channel should not affect the new channel.
//
// This is important when recreating classes that uses a channel, because the
// new instance would create the channel before the first class is deallocated
// and clears the channel.
TEST_F(FlutterEngineTest, MessengerCleanupConnectionWorks) {
  FlutterEngine* engine = GetFlutterEngine();
  EXPECT_TRUE([engine runWithEntrypoint:@"main"]);

  NSString* channel = @"_test_";
  NSData* channel_data = [channel dataUsingEncoding:NSUTF8StringEncoding];

  // Mock SendPlatformMessage so that if a message is sent to
  // "test/send_message", act as if the framework has sent an empty message to
  // the channel marked by the `sendOnChannel:message:` call's message.
  engine.embedderAPI.SendPlatformMessage = MOCK_ENGINE_PROC(
      SendPlatformMessage, ([](auto engine_, auto message_) {
        if (strcmp(message_->channel, "test/send_message") == 0) {
          // The simplest message that is acceptable to a method channel.
          std::string message = R"|({"method": "a"})|";
          std::string channel(reinterpret_cast<const char*>(message_->message),
                              message_->message_size);
          reinterpret_cast<EmbedderEngine*>(engine_)
              ->GetShell()
              .GetPlatformView()
              ->HandlePlatformMessage(std::make_unique<PlatformMessage>(
                  channel.c_str(), fml::MallocMapping::Copy(message.c_str(), message.length()),
                  fml::RefPtr<PlatformMessageResponse>()));
        }
        return kSuccess;
      }));

  __block int record = 0;

  FlutterMethodChannel* channel1 =
      [FlutterMethodChannel methodChannelWithName:channel
                                  binaryMessenger:engine.binaryMessenger
                                            codec:[FlutterJSONMethodCodec sharedInstance]];
  [channel1 setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
    record += 1;
  }];

  [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
  EXPECT_EQ(record, 1);

  FlutterMethodChannel* channel2 =
      [FlutterMethodChannel methodChannelWithName:channel
                                  binaryMessenger:engine.binaryMessenger
                                            codec:[FlutterJSONMethodCodec sharedInstance]];
  [channel2 setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
    record += 10;
  }];

  [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
  EXPECT_EQ(record, 11);

  [channel1 setMethodCallHandler:nil];

  [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
  EXPECT_EQ(record, 21);
}

TEST_F(FlutterEngineTest, HasStringsWhenPasteboardEmpty) {
  id engineMock = CreateMockFlutterEngine(nil);

  // Call hasStrings and expect it to be false.
  __block bool calledAfterClear = false;
  __block bool valueAfterClear;
  FlutterResult resultAfterClear = ^(id result) {
    calledAfterClear = true;
    NSNumber* valueNumber = [result valueForKey:@"value"];
    valueAfterClear = [valueNumber boolValue];
  };
  FlutterMethodCall* methodCallAfterClear =
      [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
  [engineMock handleMethodCall:methodCallAfterClear result:resultAfterClear];
  EXPECT_TRUE(calledAfterClear);
  EXPECT_FALSE(valueAfterClear);
}

TEST_F(FlutterEngineTest, HasStringsWhenPasteboardFull) {
  id engineMock = CreateMockFlutterEngine(@"some string");

  // Call hasStrings and expect it to be true.
  __block bool called = false;
  __block bool value;
  FlutterResult result = ^(id result) {
    called = true;
    NSNumber* valueNumber = [result valueForKey:@"value"];
    value = [valueNumber boolValue];
  };
  FlutterMethodCall* methodCall =
      [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
  [engineMock handleMethodCall:methodCall result:result];
  EXPECT_TRUE(called);
  EXPECT_TRUE(value);
}

TEST_F(FlutterEngineTest, ResponseAfterEngineDied) {
  FlutterEngine* engine = GetFlutterEngine();
  FlutterBasicMessageChannel* channel = [[FlutterBasicMessageChannel alloc]
         initWithName:@"foo"
      binaryMessenger:engine.binaryMessenger
                codec:[FlutterStandardMessageCodec sharedInstance]];
  __block BOOL didCallCallback = NO;
  [channel setMessageHandler:^(id message, FlutterReply callback) {
    ShutDownEngine();
    callback(nil);
    didCallCallback = YES;
  }];
  EXPECT_TRUE([engine runWithEntrypoint:@"sendFooMessage"]);
  engine = nil;

  while (!didCallCallback) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
  }
}

TEST_F(FlutterEngineTest, ResponseFromBackgroundThread) {
  FlutterEngine* engine = GetFlutterEngine();
  FlutterBasicMessageChannel* channel = [[FlutterBasicMessageChannel alloc]
         initWithName:@"foo"
      binaryMessenger:engine.binaryMessenger
                codec:[FlutterStandardMessageCodec sharedInstance]];
  __block BOOL didCallCallback = NO;
  [channel setMessageHandler:^(id message, FlutterReply callback) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      callback(nil);
      dispatch_async(dispatch_get_main_queue(), ^{
        didCallCallback = YES;
      });
    });
  }];
  EXPECT_TRUE([engine runWithEntrypoint:@"sendFooMessage"]);

  while (!didCallCallback) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
  }
}

TEST_F(FlutterEngineTest, ThreadSynchronizerNotBlockingRasterThreadAfterShutdown) {
  FlutterThreadSynchronizer* threadSynchronizer = [[FlutterThreadSynchronizer alloc] init];
  [threadSynchronizer shutdown];

  std::thread rasterThread([&threadSynchronizer] {
    [threadSynchronizer performCommit:CGSizeMake(100, 100)
                               notify:^{
                               }];
  });

  rasterThread.join();
}

TEST_F(FlutterEngineTest, ManageControllersIfInitiatedByController) {
  NSString* fixtures = @(flutter::testing::GetFixturesPath());
  FlutterDartProject* project = [[FlutterDartProject alloc]
      initWithAssetsPath:fixtures
             ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];

  FlutterEngine* engine;
  FlutterViewController* viewController1;

  @autoreleasepool {
    // Create FVC1.
    viewController1 = [[FlutterViewController alloc] initWithProject:project];
    EXPECT_EQ(viewController1.viewId, 0ull);

    engine = viewController1.engine;
    engine.viewController = nil;

    // Create FVC2 based on the same engine.
    FlutterViewController* viewController2 = [[FlutterViewController alloc] initWithEngine:engine
                                                                                   nibName:nil
                                                                                    bundle:nil];
    EXPECT_EQ(engine.viewController, viewController2);
  }
  // FVC2 is deallocated but FVC1 is retained.

  EXPECT_EQ(engine.viewController, nil);

  engine.viewController = viewController1;
  EXPECT_EQ(engine.viewController, viewController1);
  EXPECT_EQ(viewController1.viewId, 0ull);
}

TEST_F(FlutterEngineTest, ManageControllersIfInitiatedByEngine) {
  // Don't create the engine with `CreateMockFlutterEngine`, because it adds
  // additional references to FlutterViewControllers, which is crucial to this
  // test case.
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"io.flutter"
                                                      project:nil
                                       allowHeadlessExecution:NO];
  FlutterViewController* viewController1;

  @autoreleasepool {
    viewController1 = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
    EXPECT_EQ(viewController1.viewId, 0ull);
    EXPECT_EQ(engine.viewController, viewController1);

    engine.viewController = nil;

    FlutterViewController* viewController2 = [[FlutterViewController alloc] initWithEngine:engine
                                                                                   nibName:nil
                                                                                    bundle:nil];
    EXPECT_EQ(viewController2.viewId, 0ull);
    EXPECT_EQ(engine.viewController, viewController2);
  }
  // FVC2 is deallocated but FVC1 is retained.

  EXPECT_EQ(engine.viewController, nil);

  engine.viewController = viewController1;
  EXPECT_EQ(engine.viewController, viewController1);
  EXPECT_EQ(viewController1.viewId, 0ull);
}

TEST_F(FlutterEngineTest, HandlesTerminationRequest) {
  id engineMock = CreateMockFlutterEngine(nil);
  __block NSString* nextResponse = @"exit";
  __block BOOL triedToTerminate = FALSE;
  FlutterEngineTerminationHandler* terminationHandler =
      [[FlutterEngineTerminationHandler alloc] initWithEngine:engineMock
                                                   terminator:^(id sender) {
                                                     triedToTerminate = TRUE;
                                                     // Don't actually terminate, of course.
                                                   }];
  OCMStub([engineMock terminationHandler]).andReturn(terminationHandler);
  id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  OCMStub(  // NOLINT(google-objc-avoid-throwing-exception)
      [engineMock binaryMessenger])
      .andReturn(binaryMessengerMock);
  OCMStub([engineMock sendOnChannel:@"flutter/platform"
                            message:[OCMArg any]
                        binaryReply:[OCMArg any]])
      .andDo((^(NSInvocation* invocation) {
        [invocation retainArguments];
        FlutterBinaryReply callback;
        NSData* returnedMessage;
        [invocation getArgument:&callback atIndex:4];
        if ([nextResponse isEqualToString:@"error"]) {
          FlutterError* errorResponse = [FlutterError errorWithCode:@"Error"
                                                            message:@"Failed"
                                                            details:@"Details"];
          returnedMessage =
              [[FlutterJSONMethodCodec sharedInstance] encodeErrorEnvelope:errorResponse];
        } else {
          NSDictionary* responseDict = @{@"response" : nextResponse};
          returnedMessage =
              [[FlutterJSONMethodCodec sharedInstance] encodeSuccessEnvelope:responseDict];
        }
        callback(returnedMessage);
      }));
  __block NSString* calledAfterTerminate = @"";
  FlutterResult appExitResult = ^(id result) {
    NSDictionary* resultDict = result;
    calledAfterTerminate = resultDict[@"response"];
  };
  FlutterMethodCall* methodExitApplication =
      [FlutterMethodCall methodCallWithMethodName:@"System.exitApplication"
                                        arguments:@{@"type" : @"cancelable"}];

  triedToTerminate = FALSE;
  calledAfterTerminate = @"";
  nextResponse = @"exit";
  [engineMock handleMethodCall:methodExitApplication result:appExitResult];
  EXPECT_STREQ([calledAfterTerminate UTF8String], "exit");
  EXPECT_TRUE(triedToTerminate);

  triedToTerminate = FALSE;
  calledAfterTerminate = @"";
  nextResponse = @"cancel";
  [engineMock handleMethodCall:methodExitApplication result:appExitResult];
  EXPECT_STREQ([calledAfterTerminate UTF8String], "cancel");
  EXPECT_FALSE(triedToTerminate);

  // Check that it doesn't crash on error.
  triedToTerminate = FALSE;
  calledAfterTerminate = @"";
  nextResponse = @"error";
  [engineMock handleMethodCall:methodExitApplication result:appExitResult];
  EXPECT_STREQ([calledAfterTerminate UTF8String], "");
  EXPECT_TRUE(triedToTerminate);
}

TEST_F(FlutterEngineTest, HandleAccessibilityEvent) {
  __block BOOL announced = FALSE;
  id engineMock = CreateMockFlutterEngine(nil);

  OCMStub([engineMock announceAccessibilityMessage:[OCMArg any]
                                      withPriority:NSAccessibilityPriorityMedium])
      .andDo((^(NSInvocation* invocation) {
        announced = TRUE;
        [invocation retainArguments];
        NSString* message;
        [invocation getArgument:&message atIndex:2];
        EXPECT_EQ(message, @"error message");
      }));

  NSDictionary<NSString*, id>* annotatedEvent =
      @{@"type" : @"announce",
        @"data" : @{@"message" : @"error message"}};

  [engineMock handleAccessibilityEvent:annotatedEvent];

  EXPECT_TRUE(announced);
}

}  // namespace flutter::testing

// NOLINTEND(clang-analyzer-core.StackAddressEscape)
