// 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/Source/FlutterDisplayLink.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterVSyncWaiter.h"

#import "flutter/testing/testing.h"

@interface TestDisplayLink : FlutterDisplayLink {
}

@property(nonatomic) CFTimeInterval nominalOutputRefreshPeriod;

@end

@implementation TestDisplayLink

@synthesize nominalOutputRefreshPeriod = _nominalOutputRefreshPeriod;
@synthesize delegate = _delegate;
@synthesize paused = _paused;

- (instancetype)init {
  if (self = [super init]) {
    _paused = YES;
  }
  return self;
}

- (void)tickWithTimestamp:(CFTimeInterval)timestamp
          targetTimestamp:(CFTimeInterval)targetTimestamp {
  [_delegate onDisplayLink:timestamp targetTimestamp:targetTimestamp];
}

- (void)invalidate {
}

@end

TEST(FlutterVSyncWaiterTest, RequestsInitialVSync) {
  TestDisplayLink* displayLink = [[TestDisplayLink alloc] init];
  EXPECT_TRUE(displayLink.paused);
  // When created waiter requests a reference vsync to determine vsync phase.
  FlutterVSyncWaiter* waiter = [[FlutterVSyncWaiter alloc]
      initWithDisplayLink:displayLink
                    block:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp,
                            uintptr_t baton){
                    }];
  (void)waiter;
  EXPECT_FALSE(displayLink.paused);
  [displayLink tickWithTimestamp:CACurrentMediaTime()
                 targetTimestamp:CACurrentMediaTime() + 1.0 / 60.0];
  EXPECT_TRUE(displayLink.paused);
}

static void BusyWait(CFTimeInterval duration) {
  CFTimeInterval start = CACurrentMediaTime();
  while (CACurrentMediaTime() < start + duration) {
  }
}

// See FlutterVSyncWaiter.mm for the original definition.
static const CFTimeInterval kTimerLatencyCompensation = 0.001;

TEST(FlutterVSyncWaiterTest, FirstVSyncIsSynthesized) {
  TestDisplayLink* displayLink = [[TestDisplayLink alloc] init];
  displayLink.nominalOutputRefreshPeriod = 1.0 / 60.0;

  auto test = [&](CFTimeInterval waitDuration, CFTimeInterval expectedDelay) {
    __block CFTimeInterval timestamp = 0;
    __block CFTimeInterval targetTimestamp = 0;
    __block size_t baton = 0;
    const uintptr_t kWarmUpBaton = 0xFFFFFFFF;
    FlutterVSyncWaiter* waiter = [[FlutterVSyncWaiter alloc]
        initWithDisplayLink:displayLink
                      block:^(CFTimeInterval _timestamp, CFTimeInterval _targetTimestamp,
                              uintptr_t _baton) {
                        if (_baton == kWarmUpBaton) {
                          return;
                        }
                        timestamp = _timestamp;
                        targetTimestamp = _targetTimestamp;
                        baton = _baton;
                        EXPECT_TRUE(CACurrentMediaTime() >= _timestamp - kTimerLatencyCompensation);
                        CFRunLoopStop(CFRunLoopGetCurrent());
                      }];

    [waiter waitForVSync:kWarmUpBaton];

    // Reference vsync to setup phase.
    CFTimeInterval now = CACurrentMediaTime();
    // CVDisplayLink callback is called one and a half frame before the target.
    [displayLink tickWithTimestamp:now + 0.5 * displayLink.nominalOutputRefreshPeriod
                   targetTimestamp:now + 2 * displayLink.nominalOutputRefreshPeriod];
    EXPECT_EQ(displayLink.paused, YES);
    // Vsync was not requested yet, block should not have been called.
    EXPECT_EQ(timestamp, 0);

    BusyWait(waitDuration);

    // Synthesized vsync should come in 1/60th of a second after the first.
    CFTimeInterval expectedTimestamp = now + expectedDelay;
    [waiter waitForVSync:1];

    CFRunLoopRun();

    EXPECT_DOUBLE_EQ(timestamp, expectedTimestamp);
    EXPECT_DOUBLE_EQ(targetTimestamp, expectedTimestamp + displayLink.nominalOutputRefreshPeriod);
    EXPECT_EQ(baton, size_t(1));
  };

  // First argument if the wait duration after reference vsync.
  // Second argument is the expected delay between reference vsync and synthesized vsync.
  test(0.005, displayLink.nominalOutputRefreshPeriod);
  test(0.025, 2 * displayLink.nominalOutputRefreshPeriod);
  test(0.040, 3 * displayLink.nominalOutputRefreshPeriod);
}

TEST(FlutterVSyncWaiterTest, VSyncWorks) {
  TestDisplayLink* displayLink = [[TestDisplayLink alloc] init];
  displayLink.nominalOutputRefreshPeriod = 1.0 / 60.0;
  const uintptr_t kWarmUpBaton = 0xFFFFFFFF;

  struct Entry {
    CFTimeInterval timestamp;
    CFTimeInterval targetTimestamp;
    size_t baton;
  };
  __block std::vector<Entry> entries;

  FlutterVSyncWaiter* waiter = [[FlutterVSyncWaiter alloc]
      initWithDisplayLink:displayLink
                    block:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp,
                            uintptr_t baton) {
                      entries.push_back({timestamp, targetTimestamp, baton});
                      if (baton == kWarmUpBaton) {
                        return;
                      }
                      EXPECT_TRUE(CACurrentMediaTime() >= timestamp - kTimerLatencyCompensation);
                      CFRunLoopStop(CFRunLoopGetCurrent());
                    }];

  [waiter waitForVSync:kWarmUpBaton];

  // Reference vsync to setup phase.
  CFTimeInterval now = CACurrentMediaTime();
  // CVDisplayLink callback is called one and a half frame before the target.
  [displayLink tickWithTimestamp:now + 0.5 * displayLink.nominalOutputRefreshPeriod
                 targetTimestamp:now + 2 * displayLink.nominalOutputRefreshPeriod];
  EXPECT_EQ(displayLink.paused, YES);

  [waiter waitForVSync:1];
  CFRunLoopRun();

  [waiter waitForVSync:2];
  [displayLink tickWithTimestamp:now + 1.5 * displayLink.nominalOutputRefreshPeriod
                 targetTimestamp:now + 3 * displayLink.nominalOutputRefreshPeriod];
  CFRunLoopRun();

  [waiter waitForVSync:3];
  [displayLink tickWithTimestamp:now + 2.5 * displayLink.nominalOutputRefreshPeriod
                 targetTimestamp:now + 4 * displayLink.nominalOutputRefreshPeriod];
  CFRunLoopRun();

  EXPECT_FALSE(displayLink.paused);
  // Vsync without baton should pause the display link.
  [displayLink tickWithTimestamp:now + 3.5 * displayLink.nominalOutputRefreshPeriod
                 targetTimestamp:now + 5 * displayLink.nominalOutputRefreshPeriod];
  // Make sure to run the timer scheduled in display link callback.
  CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.02, NO);
  ASSERT_TRUE(displayLink.paused);

  EXPECT_EQ(entries.size(), size_t(4));

  // Warm up frame should be presented as soon as possible.
  EXPECT_TRUE(fabs(entries[0].timestamp - now) < 0.001);
  EXPECT_TRUE(fabs(entries[0].targetTimestamp - now) < 0.001);
  EXPECT_EQ(entries[0].baton, kWarmUpBaton);

  EXPECT_DOUBLE_EQ(entries[1].timestamp, now + displayLink.nominalOutputRefreshPeriod);
  EXPECT_DOUBLE_EQ(entries[1].targetTimestamp, now + 2 * displayLink.nominalOutputRefreshPeriod);
  EXPECT_EQ(entries[1].baton, size_t(1));
  EXPECT_DOUBLE_EQ(entries[2].timestamp, now + 2 * displayLink.nominalOutputRefreshPeriod);
  EXPECT_DOUBLE_EQ(entries[2].targetTimestamp, now + 3 * displayLink.nominalOutputRefreshPeriod);
  EXPECT_EQ(entries[2].baton, size_t(2));
  EXPECT_DOUBLE_EQ(entries[3].timestamp, now + 3 * displayLink.nominalOutputRefreshPeriod);
  EXPECT_DOUBLE_EQ(entries[3].targetTimestamp, now + 4 * displayLink.nominalOutputRefreshPeriod);
  EXPECT_EQ(entries[3].baton, size_t(3));
}
