// Copyright 2014 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 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:macrobenchmarks/src/simple_scroll.dart';

void main() {
  final IntegrationTestWidgetsFlutterBinding binding =
      IntegrationTestWidgetsFlutterBinding.ensureInitialized() as IntegrationTestWidgetsFlutterBinding;
  testWidgets(
    'Frame Counter and Input Delay for benchmarkLive',
    (WidgetTester tester) async {
      await tester.pumpWidget(const MaterialApp(home: Scaffold(body: SimpleScroll())));
      await tester.pumpAndSettle();
      final Offset location = tester.getCenter(find.byType(ListView));
      int frameCount = 0;
      void frameCounter(Duration elapsed) {
        frameCount += 1;
      }
      tester.binding.addPersistentFrameCallback(frameCounter);

      const int timeInSecond = 1;
      const Duration totalTime = Duration(seconds: timeInSecond);
      const int moveEventNumber = timeInSecond * 120;  // 120Hz
      const Offset movePerRun = Offset(0.0, -200.0 / moveEventNumber);
      final List<PointerEventRecord> records = <PointerEventRecord>[
        PointerEventRecord(Duration.zero, <PointerEvent>[
          PointerAddedEvent(
            timeStamp: Duration.zero,
            position: location,
          ),
          PointerDownEvent(
            timeStamp: Duration.zero,
            position: location,
            pointer: 1,
          ),
        ]),
        ...<PointerEventRecord>[
          for (int t=0; t < moveEventNumber; t++)
            PointerEventRecord(totalTime * (t / moveEventNumber), <PointerEvent>[
              PointerMoveEvent(
                timeStamp: totalTime * (t / moveEventNumber),
                position: location + movePerRun * t.toDouble(),
                pointer: 1,
                delta: movePerRun,
              )
            ])
        ],
        PointerEventRecord(totalTime, <PointerEvent>[
          PointerUpEvent(
            // Deviate a little from integer number of frames to reduce flakiness
            timeStamp: totalTime - const Duration(milliseconds: 1),
            position: location + movePerRun * moveEventNumber.toDouble(),
            pointer: 1,
          )
        ])
      ];

      binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.benchmarkLive;
      List<Duration> delays = await tester.handlePointerEventRecord(records);
      await tester.pumpAndSettle();
      binding.reportData = <String, dynamic>{
        'benchmarkLive': _summarizeResult(frameCount, delays),
      };
      await tester.idle();
      await tester.binding.delayed(const Duration(milliseconds: 250));

      binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
      frameCount = 0;
      delays = await tester.handlePointerEventRecord(records);
      await tester.pumpAndSettle();
      binding.reportData['fullyLive'] = _summarizeResult(frameCount, delays);
      await tester.idle();
    },
  );
}

Map<String, dynamic> _summarizeResult(
  final int frameCount,
  final List<Duration> delays,
) {
  assert(delays.length > 1);
  final List<int> delayedInMicro = delays.map<int>(
    (Duration delay) => delay.inMicroseconds,
  ).toList();
  final List<int> delayedInMicroSorted = List<int>.from(delayedInMicro)..sort();
  final int index90th = (delayedInMicroSorted.length * 0.90).round();
  final int percentile90th = delayedInMicroSorted[index90th];
  final int sum = delayedInMicroSorted.reduce((int a, int b) => a + b);
  final double averageDelay = sum.toDouble() / delayedInMicroSorted.length;
  return <String, dynamic>{
    'frame_count': frameCount,
    'average_delay_millis': averageDelay / 1E3,
    '90th_percentile_delay_millis': percentile90th / 1E3,
    if (kDebugMode)
    'delaysInMicro': delayedInMicro,
  };
}
