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

// See //dev/devicelab/bin/tasks/flutter_gallery__memory_nav.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_gallery/gallery/app.dart' show GalleryApp;
import 'package:flutter_test/flutter_test.dart';

Future<void> endOfAnimation() async {
  do {
    await SchedulerBinding.instance!.endOfFrame;
  } while (SchedulerBinding.instance!.hasScheduledFrame);
}

Rect boundsFor(WidgetController controller, Finder item) {
  final RenderBox box = controller.renderObject<RenderBox>(item);
  return box.localToGlobal(Offset.zero) & box.size;
}

Future<void> main() async {
  final Completer<void> ready = Completer<void>();
  runApp(GestureDetector(
    onTap: () {
      debugPrint('Received tap.');
      ready.complete();
    },
    behavior: HitTestBehavior.opaque,
    child: const IgnorePointer(
      ignoring: true,
      child: GalleryApp(testMode: true),
    ),
  ));
  await SchedulerBinding.instance!.endOfFrame;
  await Future<void>.delayed(const Duration(milliseconds: 50));
  debugPrint('==== MEMORY BENCHMARK ==== READY ====');

  await ready.future;
  debugPrint('Continuing...');

  // remove onTap handler, enable pointer events for app
  runApp(GestureDetector(
    child: const IgnorePointer(
      ignoring: false,
      child: GalleryApp(testMode: true),
    ),
  ));
  await SchedulerBinding.instance!.endOfFrame;

  final WidgetController controller = LiveWidgetController(WidgetsBinding.instance!);

  debugPrint('Navigating...');
  await controller.tap(find.text('Material'));
  await Future<void>.delayed(const Duration(milliseconds: 150));
  final Finder demoList = find.byKey(const Key('GalleryDemoList'));
  final Finder demoItem = find.text('Text fields');
  do {
    await controller.drag(demoList, const Offset(0.0, -300.0));
    await Future<void>.delayed(const Duration(milliseconds: 20));
  } while (!demoItem.precache());

  // Ensure that the center of the "Text fields" item is visible
  // because that's where we're going to tap
  final Rect demoItemBounds = boundsFor(controller, demoItem);
  final Rect demoListBounds = boundsFor(controller, demoList);
  if (!demoListBounds.contains(demoItemBounds.center)) {
    await controller.drag(demoList, Offset(0.0, demoListBounds.center.dy - demoItemBounds.center.dy));
    await endOfAnimation();
  }

  for (int iteration = 0; iteration < 15; iteration += 1) {
    debugPrint('Tapping... (iteration $iteration)');
    await controller.tap(demoItem);
    await endOfAnimation();
    debugPrint('Backing out...');
    await controller.tap(find.byTooltip('Back'));
    await endOfAnimation();
    await Future<void>.delayed(const Duration(milliseconds: 50));
  }

  debugPrint('==== MEMORY BENCHMARK ==== DONE ====');
}
