// Copyright 2017 The Chromium 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 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:flutter_gallery/gallery/app.dart';

/// Reports success or failure to the native code.
const MethodChannel _kTestChannel = const MethodChannel('io.flutter.examples.gallery/TestLifecycleListener');

Future<Null> main() async {
  try {
    runApp(const GalleryApp());

    const Duration kWaitBetweenActions = const Duration(milliseconds: 250);
    final _LiveWidgetController controller = new _LiveWidgetController();

    for (Demo demo in demos) {
      print('Testing "${demo.title}" demo');
      final Finder menuItem = find.text(demo.title);
      await controller.scrollIntoView(menuItem, alignment: 0.5);
      await new Future<Null>.delayed(kWaitBetweenActions);

      for (int i = 0; i < 2; i += 1) {
        await controller.tap(menuItem); // Launch the demo
        await new Future<Null>.delayed(kWaitBetweenActions);
        controller.frameSync = demo.synchronized;
        await controller.tap(find.byTooltip('Back'));
        controller.frameSync = true;
        await new Future<Null>.delayed(kWaitBetweenActions);
      }
      print('Success');
    }

    _kTestChannel.invokeMethod('success');
  } catch (error) {
    _kTestChannel.invokeMethod('failure');
  }
}

class Demo {
  const Demo(this.title, {this.synchronized = true});

  /// The title of the demo.
  final String title;

  /// True if frameSync should be enabled for this test.
  final bool synchronized;
}

// Warning: this list must be kept in sync with the value of
// kAllGalleryItems.map((GalleryItem item) => item.title).toList();
const List<Demo> demos = const <Demo>[
  // Demos
  const Demo('Shrine'),
  const Demo('Contact profile'),
  const Demo('Animation'),

  // Material Components
  const Demo('Bottom navigation'),
  const Demo('Buttons'),
  const Demo('Cards'),
  const Demo('Chips'),
  const Demo('Date and time pickers'),
  const Demo('Dialog'),
  const Demo('Drawer'),
  const Demo('Expand/collapse list control'),
  const Demo('Expansion panels'),
  const Demo('Floating action button'),
  const Demo('Grid'),
  const Demo('Icons'),
  const Demo('Leave-behind list items'),
  const Demo('List'),
  const Demo('Menus'),
  const Demo('Modal bottom sheet'),
  const Demo('Page selector'),
  const Demo('Persistent bottom sheet'),
  const Demo('Progress indicators', synchronized: false),
  const Demo('Pull to refresh'),
  const Demo('Scrollable tabs'),
  const Demo('Selection controls'),
  const Demo('Sliders'),
  const Demo('Snackbar'),
  const Demo('Tabs'),
  const Demo('Text fields'),
  const Demo('Tooltips'),

  // Cupertino Components
  const Demo('Activity Indicator', synchronized: false),
  const Demo('Buttons'),
  const Demo('Dialogs'),
  const Demo('Navigation'),
  const Demo('Sliders'),
  const Demo('Switches'),

  // Media
  const Demo('Animated images'),

  // Style
  const Demo('Colors'),
  const Demo('Typography'),
];


class _LiveWidgetController {

  final WidgetController _controller = new WidgetController(WidgetsBinding.instance);

  /// With [frameSync] enabled, Flutter Driver will wait to perform an action
  /// until there are no pending frames in the app under test.
  bool frameSync = true;

  /// Waits until at the end of a frame the provided [condition] is [true].
  Future<Null> _waitUntilFrame(bool condition(), [Completer<Null> completer]) {
    completer ??= new Completer<Null>();
    if (!condition()) {
      SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
        _waitUntilFrame(condition, completer);
      });
    } else {
      completer.complete();
    }
    return completer.future;
  }

  /// Runs `finder` repeatedly until it finds one or more [Element]s.
  Future<Finder> _waitForElement(Finder finder) async {
    if (frameSync)
      await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);

    await _waitUntilFrame(() => finder.precache());

    if (frameSync)
      await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);

    return finder;
  }

  Future<Null> tap(Finder finder) async {
    await _controller.tap(await _waitForElement(finder));
  }

  Future<Null> scrollIntoView(Finder finder, {double alignment}) async {
    final Finder target = await _waitForElement(finder);
    await Scrollable.ensureVisible(target.evaluate().single, duration: const Duration(milliseconds: 100), alignment: alignment);
  }
}
