// 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 <objc/objc.h>

#include <algorithm>
#include <functional>
#include <thread>
#include <vector>

#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/common/framework/Source/FlutterBinaryMessengerRelay.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppLifecycleDelegate.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterPluginMacOS.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"
#include "gtest/gtest.h"

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

constexpr int64_t kImplicitViewId = 0ll;

@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

@interface PlainAppDelegate : NSObject <NSApplicationDelegate>
@end

@implementation PlainAppDelegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication* _Nonnull)sender {
  // Always cancel, so that the test doesn't exit.
  return NSTerminateCancel;
}
@end

#pragma mark -

@interface FakeLifecycleProvider : NSObject <FlutterAppLifecycleProvider, NSApplicationDelegate>

@property(nonatomic, strong, readonly) NSPointerArray* registeredDelegates;

// True if the given delegate is currently registered.
- (BOOL)hasDelegate:(nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate;
@end

@implementation FakeLifecycleProvider {
  /**
   * All currently registered delegates.
   *
   * This does not use NSPointerArray or any other weak-pointer
   * system, because a weak pointer will be nil'd out at the start of dealloc, which will break
   * queries. E.g., if a delegate is dealloc'd without being unregistered, a weak pointer array
   * would no longer contain that pointer even though removeApplicationLifecycleDelegate: was never
   * called, causing tests to pass incorrectly.
   */
  std::vector<void*> _delegates;
}

- (void)addApplicationLifecycleDelegate:(nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate {
  _delegates.push_back((__bridge void*)delegate);
}

- (void)removeApplicationLifecycleDelegate:
    (nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate {
  auto delegateIndex = std::find(_delegates.begin(), _delegates.end(), (__bridge void*)delegate);
  NSAssert(delegateIndex != _delegates.end(),
           @"Attempting to unregister a delegate that was not registered.");
  _delegates.erase(delegateIndex);
}

- (BOOL)hasDelegate:(nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate {
  return std::find(_delegates.begin(), _delegates.end(), (__bridge void*)delegate) !=
         _delegates.end();
}

@end

#pragma mark -

@interface FakeAppDelegatePlugin : NSObject <FlutterPlugin>
@end

@implementation FakeAppDelegatePlugin
+ (void)registerWithRegistrar:(id<FlutterPluginRegistrar>)registrar {
}
@end

#pragma mark -

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);
}

// TODO(cbracken): Needs deflaking. https://github.com/flutter/flutter/issues/124677
TEST_F(FlutterEngineTest, DISABLED_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();
}

// TODO(cbracken): Needs deflaking. https://github.com/flutter/flutter/issues/124677
TEST_F(FlutterEngineTest, DISABLED_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 implicit 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){
                }];

  [engine.testThreadSynchronizer 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);
}

// Verify that the engine is not retained indirectly via the binary messenger held by channels and
// plugins. Previously, FlutterEngine.binaryMessenger returned the engine itself, and thus plugins
// could cause a retain cycle, preventing the engine from being deallocated.
// FlutterEngine.binaryMessenger now returns a FlutterBinaryMessengerRelay whose weak pointer back
// to the engine is cleared when the engine is deallocated.
// Issue: https://github.com/flutter/flutter/issues/116445
TEST_F(FlutterEngineTest, FlutterBinaryMessengerDoesNotRetainEngine) {
  __weak FlutterEngine* weakEngine;
  id<FlutterBinaryMessenger> binaryMessenger = nil;
  @autoreleasepool {
    // Create a test engine.
    NSString* fixtures = @(flutter::testing::GetFixturesPath());
    FlutterDartProject* project = [[FlutterDartProject alloc]
        initWithAssetsPath:fixtures
               ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
                                                        project:project
                                         allowHeadlessExecution:YES];
    weakEngine = engine;
    binaryMessenger = engine.binaryMessenger;
  }

  // Once the engine has been deallocated, verify the weak engine pointer is nil, and thus not
  // retained by the relay.
  EXPECT_NE(binaryMessenger, nil);
  EXPECT_EQ(weakEngine, nil);
}

// Verify that the engine is not retained indirectly via the texture registry held by plugins.
// Issue: https://github.com/flutter/flutter/issues/116445
TEST_F(FlutterEngineTest, FlutterTextureRegistryDoesNotReturnEngine) {
  __weak FlutterEngine* weakEngine;
  id<FlutterTextureRegistry> textureRegistry;
  @autoreleasepool {
    // Create a test engine.
    NSString* fixtures = @(flutter::testing::GetFixturesPath());
    FlutterDartProject* project = [[FlutterDartProject alloc]
        initWithAssetsPath:fixtures
               ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
                                                        project:project
                                         allowHeadlessExecution:YES];
    id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:@"MyPlugin"];
    textureRegistry = registrar.textures;
  }

  // Once the engine has been deallocated, verify the weak engine pointer is nil, and thus not
  // retained via the texture registry.
  EXPECT_NE(textureRegistry, nil);
  EXPECT_EQ(weakEngine, nil);
}

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

  EXPECT_EQ([engine valuePublishedByPlugin:@"NoSuchPlugin"], nil);
}

TEST_F(FlutterEngineTest, PublishedValueNSNullIfNoPublishedValue) {
  NSString* fixtures = @(flutter::testing::GetFixturesPath());
  FlutterDartProject* project = [[FlutterDartProject alloc]
      initWithAssetsPath:fixtures
             ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
                                                      project:project
                                       allowHeadlessExecution:YES];
  NSString* pluginName = @"MyPlugin";
  // Request the registarar to register the plugin as existing.
  [engine registrarForPlugin:pluginName];

  // The documented behavior is that a plugin that exists but hasn't published
  // anything returns NSNull, rather than nil, as on iOS.
  EXPECT_EQ([engine valuePublishedByPlugin:pluginName], [NSNull null]);
}

TEST_F(FlutterEngineTest, PublishedValueReturnsLastPublished) {
  NSString* fixtures = @(flutter::testing::GetFixturesPath());
  FlutterDartProject* project = [[FlutterDartProject alloc]
      initWithAssetsPath:fixtures
             ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
                                                      project:project
                                       allowHeadlessExecution:YES];
  NSString* pluginName = @"MyPlugin";
  id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:pluginName];

  NSString* firstValue = @"A published value";
  NSArray* secondValue = @[ @"A different published value" ];

  [registrar publish:firstValue];
  EXPECT_EQ([engine valuePublishedByPlugin:pluginName], firstValue);

  [registrar publish:secondValue];
  EXPECT_EQ([engine valuePublishedByPlugin:pluginName], secondValue);
}

// 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 performCommitForView:kImplicitViewId
                                        size: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, 0ll);

    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, 0ll);
}

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, 0ll);
    EXPECT_EQ(engine.viewController, viewController1);

    engine.viewController = nil;

    FlutterViewController* viewController2 = [[FlutterViewController alloc] initWithEngine:engine
                                                                                   nibName:nil
                                                                                    bundle:nil];
    EXPECT_EQ(viewController2.viewId, 0ll);
    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, 0ll);
}

TEST_F(FlutterEngineTest, HandlesTerminationRequest) {
  id engineMock = CreateMockFlutterEngine(nil);
  __block NSString* nextResponse = @"exit";
  __block BOOL triedToTerminate = NO;
  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"}];

  // Always terminate when the binding isn't ready (which is the default).
  triedToTerminate = NO;
  calledAfterTerminate = @"";
  nextResponse = @"cancel";
  [engineMock handleMethodCall:methodExitApplication result:appExitResult];
  EXPECT_STREQ([calledAfterTerminate UTF8String], "");
  EXPECT_TRUE(triedToTerminate);

  // Once the binding is ready, handle the request.
  terminationHandler.acceptingRequests = YES;
  triedToTerminate = NO;
  calledAfterTerminate = @"";
  nextResponse = @"exit";
  [engineMock handleMethodCall:methodExitApplication result:appExitResult];
  EXPECT_STREQ([calledAfterTerminate UTF8String], "exit");
  EXPECT_TRUE(triedToTerminate);

  triedToTerminate = NO;
  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 = NO;
  calledAfterTerminate = @"";
  nextResponse = @"error";
  [engineMock handleMethodCall:methodExitApplication result:appExitResult];
  EXPECT_STREQ([calledAfterTerminate UTF8String], "");
  EXPECT_TRUE(triedToTerminate);
}

TEST_F(FlutterEngineTest, IgnoresTerminationRequestIfNotFlutterAppDelegate) {
  id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
  id<NSApplicationDelegate> plainDelegate = [[PlainAppDelegate alloc] init];
  [NSApplication sharedApplication].delegate = plainDelegate;

  // Creating the engine shouldn't fail here, even though the delegate isn't a
  // FlutterAppDelegate.
  CreateMockFlutterEngine(nil);

  // Asking to terminate the app should cancel.
  EXPECT_EQ([[[NSApplication sharedApplication] delegate] applicationShouldTerminate:NSApp],
            NSTerminateCancel);

  [NSApplication sharedApplication].delegate = previousDelegate;
}

TEST_F(FlutterEngineTest, HandleAccessibilityEvent) {
  __block BOOL announced = NO;
  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);
}

TEST_F(FlutterEngineTest, HandleLifecycleStates) API_AVAILABLE(macos(10.9)) {
  __block flutter::AppLifecycleState sentState;
  id engineMock = CreateMockFlutterEngine(nil);

  // Have to enumerate all the values because OCMStub can't capture
  // non-Objective-C object arguments.
  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kDetached])
      .andDo((^(NSInvocation* invocation) {
        sentState = flutter::AppLifecycleState::kDetached;
      }));
  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kResumed])
      .andDo((^(NSInvocation* invocation) {
        sentState = flutter::AppLifecycleState::kResumed;
      }));
  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kInactive])
      .andDo((^(NSInvocation* invocation) {
        sentState = flutter::AppLifecycleState::kInactive;
      }));
  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kHidden])
      .andDo((^(NSInvocation* invocation) {
        sentState = flutter::AppLifecycleState::kHidden;
      }));
  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kPaused])
      .andDo((^(NSInvocation* invocation) {
        sentState = flutter::AppLifecycleState::kPaused;
      }));

  __block NSApplicationOcclusionState visibility = NSApplicationOcclusionStateVisible;
  id mockApplication = OCMPartialMock([NSApplication sharedApplication]);
  OCMStub((NSApplicationOcclusionState)[mockApplication occlusionState])
      .andDo(^(NSInvocation* invocation) {
        [invocation setReturnValue:&visibility];
      });

  NSNotification* willBecomeActive =
      [[NSNotification alloc] initWithName:NSApplicationWillBecomeActiveNotification
                                    object:nil
                                  userInfo:nil];
  NSNotification* willResignActive =
      [[NSNotification alloc] initWithName:NSApplicationWillResignActiveNotification
                                    object:nil
                                  userInfo:nil];

  NSNotification* didChangeOcclusionState;
  didChangeOcclusionState =
      [[NSNotification alloc] initWithName:NSApplicationDidChangeOcclusionStateNotification
                                    object:nil
                                  userInfo:nil];

  [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
  EXPECT_EQ(sentState, flutter::AppLifecycleState::kInactive);

  [engineMock handleWillBecomeActive:willBecomeActive];
  EXPECT_EQ(sentState, flutter::AppLifecycleState::kResumed);

  [engineMock handleWillResignActive:willResignActive];
  EXPECT_EQ(sentState, flutter::AppLifecycleState::kInactive);

  visibility = 0;
  [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
  EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);

  [engineMock handleWillBecomeActive:willBecomeActive];
  EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);

  [engineMock handleWillResignActive:willResignActive];
  EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);

  [mockApplication stopMocking];
}

TEST_F(FlutterEngineTest, ForwardsPluginDelegateRegistration) {
  id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
  FakeLifecycleProvider* fakeAppDelegate = [[FakeLifecycleProvider alloc] init];
  [NSApplication sharedApplication].delegate = fakeAppDelegate;

  FakeAppDelegatePlugin* plugin = [[FakeAppDelegatePlugin alloc] init];
  FlutterEngine* engine = CreateMockFlutterEngine(nil);

  [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];

  EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);

  [NSApplication sharedApplication].delegate = previousDelegate;
}

TEST_F(FlutterEngineTest, UnregistersPluginsOnEngineDestruction) {
  id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
  FakeLifecycleProvider* fakeAppDelegate = [[FakeLifecycleProvider alloc] init];
  [NSApplication sharedApplication].delegate = fakeAppDelegate;

  FakeAppDelegatePlugin* plugin = [[FakeAppDelegatePlugin alloc] init];

  @autoreleasepool {
    FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];

    [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
    EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
  }

  // When the engine is released, it should unregister any plugins it had
  // registered on its behalf.
  EXPECT_FALSE([fakeAppDelegate hasDelegate:plugin]);

  [NSApplication sharedApplication].delegate = previousDelegate;
}

}  // namespace flutter::testing

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