// 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/cupertino.dart';
import 'package:flutter_gallery/demo_lists.dart';
import 'package:flutter_test/flutter_test.dart';

/// The demos we don't run as part of the integration test.
///
/// Demo names are formatted as 'DEMO_NAME@DEMO_CATEGORY' (see
/// `demo_lists.dart` for more examples).
final List<String> kSkippedDemos = <String>[
  // This demo is flaky on CI due to hitting the network.
  // See: https://github.com/flutter/flutter/issues/100497
  'Video@Media',
];

/// Scrolls each demo menu item into view, launches it, then returns to the
/// home screen twice.
Future<void> runDemos(List<String> demos, WidgetController controller) async {
  final Finder demoList = find.byType(Scrollable);
  String? currentDemoCategory;

  for (final String demo in demos) {
    if (kSkippedDemos.contains(demo))
      continue;

    final String demoName = demo.substring(0, demo.indexOf('@'));
    final String demoCategory = demo.substring(demo.indexOf('@') + 1);
    print('> $demo');
    await controller.pump(const Duration(milliseconds: 250));

    final Finder demoCategoryItem = find.text(demoCategory);
    if (currentDemoCategory == null) {
      await controller.scrollUntilVisible(demoCategoryItem, 48.0);
      await controller.tap(demoCategoryItem);
      await controller.pumpAndSettle();
    } else if (currentDemoCategory != demoCategory) {
      await controller.tap(find.byTooltip('Back'));
      await controller.pumpAndSettle();
      await controller.scrollUntilVisible(demoCategoryItem, 48.0);
      await controller.tap(demoCategoryItem);
      await controller.pumpAndSettle();
      // Scroll back to the top
      await controller.drag(demoList, const Offset(0.0, 10000.0));
      await controller.pumpAndSettle();
    }
    currentDemoCategory = demoCategory;

    Future<void> pageBack() {
      Finder backButton = find.byTooltip('Back');
      if (backButton.evaluate().isEmpty) {
        backButton = find.byType(CupertinoNavigationBarBackButton);
      }
      return controller.tap(backButton);
    }

    for (int i = 0; i < 2; i += 1) {
      final Finder demoItem = find.text(demoName);
      await controller.scrollUntilVisible(demoItem, 48.0);
      await controller.pumpAndSettle();
      if (demoItem.evaluate().isEmpty) {
        print('Failed to find $demoItem');
        print('All available elements:');
        print(controller.allElements.toList().join('\n'));
        print('App structure:');
        debugDumpApp();
        throw TestFailure('Failed to find element');
      }
      await controller.tap(demoItem); // Launch the demo

      if (kUnsynchronizedDemos.contains(demo)) {
        // These tests have animation, pumpAndSettle cannot be used.
        // This time is questionable. 400ms is the tested reasonable result.
        await controller.pump(const Duration(milliseconds: 400));
        await controller.pump();
        await pageBack();
      } else {
        await controller.pumpAndSettle();
        // page back
        await pageBack();
      }
      await controller.pumpAndSettle();
    }

    print('< Success');
  }

  // Return to the home screen
  await controller.tap(find.byTooltip('Back'));
  await controller.pumpAndSettle();
}
