// 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/material.dart';
import 'package:flutter/gestures.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,
  };
}
