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

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"

FLUTTER_ASSERT_NOT_ARC

@interface UITouch ()

@property(nonatomic, readwrite) UITouchPhase phase;

@end

@interface VSyncClient (Testing)

- (CADisplayLink*)getDisplayLink;

@end

@interface FlutterViewController (Testing)

@property(nonatomic, assign) double targetViewInsetBottom;
@property(nonatomic, retain) VSyncClient* keyboardAnimationVSyncClient;

@property(nonatomic, retain) VSyncClient* touchRateCorrectionVSyncClient;

- (void)createTouchRateCorrectionVSyncClientIfNeeded;
- (void)setupKeyboardAnimationVsyncClient;
- (void)triggerTouchRateCorrectionIfNeeded:(NSSet*)touches;

@end

@interface FlutterViewControllerTest_mrc : XCTestCase
@end

@implementation FlutterViewControllerTest_mrc

- (void)testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController {
  id bundleMock = OCMPartialMock([NSBundle mainBundle]);
  OCMStub([bundleMock objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"])
      .andReturn(@YES);
  id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
  double maxFrameRate = 120;
  [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine runWithEntrypoint:nil];
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController setupKeyboardAnimationVsyncClient];
  XCTAssertNotNil(viewController.keyboardAnimationVSyncClient);
  CADisplayLink* link = [viewController.keyboardAnimationVSyncClient getDisplayLink];
  XCTAssertNotNil(link);
  if (@available(iOS 15.0, *)) {
    XCTAssertEqual(link.preferredFrameRateRange.maximum, maxFrameRate);
    XCTAssertEqual(link.preferredFrameRateRange.preferred, maxFrameRate);
    XCTAssertEqual(link.preferredFrameRateRange.minimum, maxFrameRate / 2);
  } else {
    XCTAssertEqual(link.preferredFramesPerSecond, maxFrameRate);
  }
}

- (void)
    testCreateTouchRateCorrectionVSyncClientWillCreateVsyncClientWhenRefreshRateIsLargerThan60HZ {
  id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
  double maxFrameRate = 120;
  [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine runWithEntrypoint:nil];
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController createTouchRateCorrectionVSyncClientIfNeeded];
  XCTAssertNotNil(viewController.touchRateCorrectionVSyncClient);
}

- (void)testCreateTouchRateCorrectionVSyncClientWillNotCreateNewVSyncClientWhenClientAlreadyExists {
  id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
  double maxFrameRate = 120;
  [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];

  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine runWithEntrypoint:nil];
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController createTouchRateCorrectionVSyncClientIfNeeded];
  VSyncClient* clientBefore = viewController.touchRateCorrectionVSyncClient;
  XCTAssertNotNil(clientBefore);

  [viewController createTouchRateCorrectionVSyncClientIfNeeded];
  VSyncClient* clientAfter = viewController.touchRateCorrectionVSyncClient;
  XCTAssertNotNil(clientAfter);

  XCTAssertTrue(clientBefore == clientAfter);
}

- (void)testCreateTouchRateCorrectionVSyncClientWillNotCreateVsyncClientWhenRefreshRateIs60HZ {
  id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
  double maxFrameRate = 60;
  [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine runWithEntrypoint:nil];
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController createTouchRateCorrectionVSyncClientIfNeeded];
  XCTAssertNil(viewController.touchRateCorrectionVSyncClient);
}

- (void)testTriggerTouchRateCorrectionVSyncClientCorrectly {
  id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
  double maxFrameRate = 120;
  [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
  FlutterEngine* engine = [[FlutterEngine alloc] init];
  [engine runWithEntrypoint:nil];
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController loadView];
  [viewController viewDidLoad];

  VSyncClient* client = viewController.touchRateCorrectionVSyncClient;
  CADisplayLink* link = [client getDisplayLink];

  UITouch* fakeTouchBegan = [[UITouch alloc] init];
  fakeTouchBegan.phase = UITouchPhaseBegan;

  UITouch* fakeTouchMove = [[UITouch alloc] init];
  fakeTouchMove.phase = UITouchPhaseMoved;

  UITouch* fakeTouchEnd = [[UITouch alloc] init];
  fakeTouchEnd.phase = UITouchPhaseEnded;

  UITouch* fakeTouchCancelled = [[UITouch alloc] init];
  fakeTouchCancelled.phase = UITouchPhaseCancelled;

  [viewController
      triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchBegan, nil]];
  XCTAssertFalse(link.isPaused);

  [viewController
      triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchEnd, nil]];
  XCTAssertTrue(link.isPaused);

  [viewController
      triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchMove, nil]];
  XCTAssertFalse(link.isPaused);

  [viewController
      triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchCancelled, nil]];
  XCTAssertTrue(link.isPaused);

  [viewController
      triggerTouchRateCorrectionIfNeeded:[[NSSet alloc]
                                             initWithObjects:fakeTouchBegan, fakeTouchEnd, nil]];
  XCTAssertFalse(link.isPaused);

  [viewController
      triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchEnd,
                                                                        fakeTouchCancelled, nil]];
  XCTAssertTrue(link.isPaused);

  [viewController
      triggerTouchRateCorrectionIfNeeded:[[NSSet alloc]
                                             initWithObjects:fakeTouchMove, fakeTouchEnd, nil]];
  XCTAssertFalse(link.isPaused);
}

@end
