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

@TestOn('!chrome') // entire file needs triage.
import 'dart:async';
import 'dart:ui' as ui;

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

import '../rendering/mock_canvas.dart';
import '../rendering/recording_canvas.dart';
import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart';

final Finder _hourControl = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl');
final Finder _minuteControl = find.byWidgetPredicate((Widget widget) => '${widget.runtimeType}' == '_MinuteControl');
final Finder _timePickerDialog = find.byWidgetPredicate((Widget widget) => '${widget.runtimeType}' == '_TimePickerDialog');

class _TimePickerLauncher extends StatelessWidget {
  const _TimePickerLauncher({ Key key, this.onChanged, this.locale }) : super(key: key);

  final ValueChanged<TimeOfDay> onChanged;
  final Locale locale;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: locale,
      home: Material(
        child: Center(
          child: Builder(
            builder: (BuildContext context) {
              return RaisedButton(
                child: const Text('X'),
                onPressed: () async {
                  onChanged(await showTimePicker(
                    context: context,
                    initialTime: const TimeOfDay(hour: 7, minute: 0),
                  ));
                },
              );
            }
          ),
        ),
      ),
    );
  }
}

Future<Offset> startPicker(WidgetTester tester, ValueChanged<TimeOfDay> onChanged) async {
  await tester.pumpWidget(_TimePickerLauncher(onChanged: onChanged, locale: const Locale('en', 'US')));
  await tester.tap(find.text('X'));
  await tester.pumpAndSettle(const Duration(seconds: 1));
  return tester.getCenter(find.byKey(const ValueKey<String>('time-picker-dial')));
}

Future<void> finishPicker(WidgetTester tester) async {
  final MaterialLocalizations materialLocalizations = MaterialLocalizations.of(tester.element(find.byType(RaisedButton)));
  await tester.tap(find.text(materialLocalizations.okButtonLabel));
  await tester.pumpAndSettle(const Duration(seconds: 1));
}

void main() {
  group('Time picker', () {
    _tests();
  });
}

void _tests() {
  testWidgets('tap-select an hour', (WidgetTester tester) async {
    TimeOfDay result;

    Offset center = await startPicker(tester, (TimeOfDay time) { result = time; });
    await tester.tapAt(Offset(center.dx, center.dy - 50.0)); // 12:00 AM
    await finishPicker(tester);
    expect(result, equals(const TimeOfDay(hour: 0, minute: 0)));

    center = await startPicker(tester, (TimeOfDay time) { result = time; });
    await tester.tapAt(Offset(center.dx + 50.0, center.dy));
    await finishPicker(tester);
    expect(result, equals(const TimeOfDay(hour: 3, minute: 0)));

    center = await startPicker(tester, (TimeOfDay time) { result = time; });
    await tester.tapAt(Offset(center.dx, center.dy + 50.0));
    await finishPicker(tester);
    expect(result, equals(const TimeOfDay(hour: 6, minute: 0)));

    center = await startPicker(tester, (TimeOfDay time) { result = time; });
    await tester.tapAt(Offset(center.dx, center.dy + 50.0));
    await tester.tapAt(Offset(center.dx - 50, center.dy));
    await finishPicker(tester);
    expect(result, equals(const TimeOfDay(hour: 9, minute: 0)));
  });

  testWidgets('drag-select an hour', (WidgetTester tester) async {
    TimeOfDay result;

    final Offset center = await startPicker(tester, (TimeOfDay time) { result = time; });
    final Offset hour0 = Offset(center.dx, center.dy - 50.0); // 12:00 AM
    final Offset hour3 = Offset(center.dx + 50.0, center.dy);
    final Offset hour6 = Offset(center.dx, center.dy + 50.0);
    final Offset hour9 = Offset(center.dx - 50.0, center.dy);

    TestGesture gesture;

    gesture = await tester.startGesture(hour3);
    await gesture.moveBy(hour0 - hour3);
    await gesture.up();
    await finishPicker(tester);
    expect(result.hour, 0);

    expect(await startPicker(tester, (TimeOfDay time) { result = time; }), equals(center));
    gesture = await tester.startGesture(hour0);
    await gesture.moveBy(hour3 - hour0);
    await gesture.up();
    await finishPicker(tester);
    expect(result.hour, 3);

    expect(await startPicker(tester, (TimeOfDay time) { result = time; }), equals(center));
    gesture = await tester.startGesture(hour3);
    await gesture.moveBy(hour6 - hour3);
    await gesture.up();
    await finishPicker(tester);
    expect(result.hour, equals(6));

    expect(await startPicker(tester, (TimeOfDay time) { result = time; }), equals(center));
    gesture = await tester.startGesture(hour6);
    await gesture.moveBy(hour9 - hour6);
    await gesture.up();
    await finishPicker(tester);
    expect(result.hour, equals(9));
  });

  testWidgets('tap-select switches from hour to minute', (WidgetTester tester) async {
    TimeOfDay result;

    final Offset center = await startPicker(tester, (TimeOfDay time) { result = time; });
    final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
    final Offset min45 = Offset(center.dx - 50.0, center.dy); // 45 mins (or 9:00 hours)

    await tester.tapAt(hour6);
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tapAt(min45);
    await finishPicker(tester);
    expect(result, equals(const TimeOfDay(hour: 6, minute: 45)));
  });

  testWidgets('drag-select switches from hour to minute', (WidgetTester tester) async {
    TimeOfDay result;

    final Offset center = await startPicker(tester, (TimeOfDay time) { result = time; });
    final Offset hour3 = Offset(center.dx + 50.0, center.dy);
    final Offset hour6 = Offset(center.dx, center.dy + 50.0);
    final Offset hour9 = Offset(center.dx - 50.0, center.dy);

    TestGesture gesture = await tester.startGesture(hour6);
    await gesture.moveBy(hour9 - hour6);
    await gesture.up();
    await tester.pump(const Duration(milliseconds: 50));
    gesture = await tester.startGesture(hour6);
    await gesture.moveBy(hour3 - hour6);
    await gesture.up();
    await finishPicker(tester);
    expect(result, equals(const TimeOfDay(hour: 9, minute: 15)));
  });

  group('haptic feedback', () {
    const Duration kFastFeedbackInterval = Duration(milliseconds: 10);
    const Duration kSlowFeedbackInterval = Duration(milliseconds: 200);
    FeedbackTester feedback;

    setUp(() {
      feedback = FeedbackTester();
    });

    tearDown(() {
      feedback?.dispose();
    });

    testWidgets('tap-select vibrates once', (WidgetTester tester) async {
      final Offset center = await startPicker(tester, (TimeOfDay time) { });
      await tester.tapAt(Offset(center.dx, center.dy - 50.0));
      await finishPicker(tester);
      expect(feedback.hapticCount, 1);
    });

    testWidgets('quick successive tap-selects vibrate once', (WidgetTester tester) async {
      final Offset center = await startPicker(tester, (TimeOfDay time) { });
      await tester.tapAt(Offset(center.dx, center.dy - 50.0));
      await tester.pump(kFastFeedbackInterval);
      await tester.tapAt(Offset(center.dx, center.dy + 50.0));
      await finishPicker(tester);
      expect(feedback.hapticCount, 1);
    });

    testWidgets('slow successive tap-selects vibrate once per tap', (WidgetTester tester) async {
      final Offset center = await startPicker(tester, (TimeOfDay time) { });
      await tester.tapAt(Offset(center.dx, center.dy - 50.0));
      await tester.pump(kSlowFeedbackInterval);
      await tester.tapAt(Offset(center.dx, center.dy + 50.0));
      await tester.pump(kSlowFeedbackInterval);
      await tester.tapAt(Offset(center.dx, center.dy - 50.0));
      await finishPicker(tester);
      expect(feedback.hapticCount, 3);
    });

    testWidgets('drag-select vibrates once', (WidgetTester tester) async {
      final Offset center = await startPicker(tester, (TimeOfDay time) { });
      final Offset hour0 = Offset(center.dx, center.dy - 50.0);
      final Offset hour3 = Offset(center.dx + 50.0, center.dy);

      final TestGesture gesture = await tester.startGesture(hour3);
      await gesture.moveBy(hour0 - hour3);
      await gesture.up();
      await finishPicker(tester);
      expect(feedback.hapticCount, 1);
    });

    testWidgets('quick drag-select vibrates once', (WidgetTester tester) async {
      final Offset center = await startPicker(tester, (TimeOfDay time) { });
      final Offset hour0 = Offset(center.dx, center.dy - 50.0);
      final Offset hour3 = Offset(center.dx + 50.0, center.dy);

      final TestGesture gesture = await tester.startGesture(hour3);
      await gesture.moveBy(hour0 - hour3);
      await tester.pump(kFastFeedbackInterval);
      await gesture.moveBy(hour3 - hour0);
      await tester.pump(kFastFeedbackInterval);
      await gesture.moveBy(hour0 - hour3);
      await gesture.up();
      await finishPicker(tester);
      expect(feedback.hapticCount, 1);
    });

    testWidgets('slow drag-select vibrates once', (WidgetTester tester) async {
      final Offset center = await startPicker(tester, (TimeOfDay time) { });
      final Offset hour0 = Offset(center.dx, center.dy - 50.0);
      final Offset hour3 = Offset(center.dx + 50.0, center.dy);

      final TestGesture gesture = await tester.startGesture(hour3);
      await gesture.moveBy(hour0 - hour3);
      await tester.pump(kSlowFeedbackInterval);
      await gesture.moveBy(hour3 - hour0);
      await tester.pump(kSlowFeedbackInterval);
      await gesture.moveBy(hour0 - hour3);
      await gesture.up();
      await finishPicker(tester);
      expect(feedback.hapticCount, 3);
    });
  });

  const List<String> labels12To11 = <String>['12', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'];
  const List<String> labels12To11TwoDigit = <String>['12', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11'];
  const List<String> labels00To23 = <String>['00', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];

  Future<void> mediaQueryBoilerplate(
    WidgetTester tester,
    bool alwaysUse24HourFormat, {
    TimeOfDay initialTime = const TimeOfDay(hour: 7, minute: 0),
  }) async {
    await tester.pumpWidget(
      Localizations(
        locale: const Locale('en', 'US'),
        delegates: const <LocalizationsDelegate<dynamic>>[
          DefaultMaterialLocalizations.delegate,
          DefaultWidgetsLocalizations.delegate,
        ],
        child: MediaQuery(
          data: MediaQueryData(alwaysUse24HourFormat: alwaysUse24HourFormat),
          child: Material(
            child: Directionality(
              textDirection: TextDirection.ltr,
              child: Navigator(
                onGenerateRoute: (RouteSettings settings) {
                  return MaterialPageRoute<void>(builder: (BuildContext context) {
                    return FlatButton(
                      onPressed: () {
                        showTimePicker(context: context, initialTime: initialTime);
                      },
                      child: const Text('X'),
                    );
                  });
                },
              ),
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('X'));
    await tester.pumpAndSettle();
  }

  testWidgets('respects MediaQueryData.alwaysUse24HourFormat == false', (WidgetTester tester) async {
    await mediaQueryBoilerplate(tester, false);

    final CustomPaint dialPaint = tester.widget(findDialPaint);
    final dynamic dialPainter = dialPaint.painter;
    final List<dynamic> primaryOuterLabels = dialPainter.primaryOuterLabels;
    expect(primaryOuterLabels.map<String>((dynamic tp) => tp.painter.text.text), labels12To11);
    expect(dialPainter.primaryInnerLabels, null);

    final List<dynamic> secondaryOuterLabels = dialPainter.secondaryOuterLabels;
    expect(secondaryOuterLabels.map<String>((dynamic tp) => tp.painter.text.text), labels12To11);
    expect(dialPainter.secondaryInnerLabels, null);
  });

  testWidgets('respects MediaQueryData.alwaysUse24HourFormat == true', (WidgetTester tester) async {
    await mediaQueryBoilerplate(tester, true);

    final CustomPaint dialPaint = tester.widget(findDialPaint);
    final dynamic dialPainter = dialPaint.painter;
    final List<dynamic> primaryOuterLabels = dialPainter.primaryOuterLabels;
    expect(primaryOuterLabels.map<String>((dynamic tp) => tp.painter.text.text), labels00To23);
    final List<dynamic> primaryInnerLabels = dialPainter.primaryInnerLabels;
    expect(primaryInnerLabels.map<String>((dynamic tp) => tp.painter.text.text), labels12To11TwoDigit);

    final List<dynamic> secondaryOuterLabels = dialPainter.secondaryOuterLabels;
    expect(secondaryOuterLabels.map<String>((dynamic tp) => tp.painter.text.text), labels00To23);
    final List<dynamic> secondaryInnerLabels = dialPainter.secondaryInnerLabels;
    expect(secondaryInnerLabels.map<String>((dynamic tp) => tp.painter.text.text), labels12To11TwoDigit);
  });

  testWidgets('provides semantics information for AM/PM indicator', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    await mediaQueryBoilerplate(tester, false);

    expect(semantics, includesNodeWith(label: 'AM', actions: <SemanticsAction>[SemanticsAction.tap]));
    expect(semantics, includesNodeWith(label: 'PM', actions: <SemanticsAction>[SemanticsAction.tap]));

    semantics.dispose();
  });

  testWidgets('provides semantics information for header and footer', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    await mediaQueryBoilerplate(tester, true);

    expect(semantics, isNot(includesNodeWith(label: ':')));
    expect(semantics.nodesWith(value: '00'), hasLength(2),
        reason: '00 appears once in the header, then again in the dial');
    expect(semantics.nodesWith(value: '07'), hasLength(2),
        reason: '07 appears once in the header, then again in the dial');
    expect(semantics, includesNodeWith(label: 'CANCEL'));
    expect(semantics, includesNodeWith(label: 'OK'));

    // In 24-hour mode we don't have AM/PM control.
    expect(semantics, isNot(includesNodeWith(label: 'AM')));
    expect(semantics, isNot(includesNodeWith(label: 'PM')));

    semantics.dispose();
  });

  testWidgets('provides semantics information for hours', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    await mediaQueryBoilerplate(tester, true);

    final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
    final CustomPainter dialPainter = dialPaint.painter;
    final _CustomPainterSemanticsTester painterTester = _CustomPainterSemanticsTester(tester, dialPainter, semantics);

    painterTester.addLabel('00', 86.0, 0.0, 134.0, 48.0);
    painterTester.addLabel('13', 129.0, 11.5, 177.0, 59.5);
    painterTester.addLabel('14', 160.5, 43.0, 208.5, 91.0);
    painterTester.addLabel('15', 172.0, 86.0, 220.0, 134.0);
    painterTester.addLabel('16', 160.5, 129.0, 208.5, 177.0);
    painterTester.addLabel('17', 129.0, 160.5, 177.0, 208.5);
    painterTester.addLabel('18', 86.0, 172.0, 134.0, 220.0);
    painterTester.addLabel('19', 43.0, 160.5, 91.0, 208.5);
    painterTester.addLabel('20', 11.5, 129.0, 59.5, 177.0);
    painterTester.addLabel('21', 0.0, 86.0, 48.0, 134.0);
    painterTester.addLabel('22', 11.5, 43.0, 59.5, 91.0);
    painterTester.addLabel('23', 43.0, 11.5, 91.0, 59.5);
    painterTester.addLabel('12', 86.0, 36.0, 134.0, 84.0);
    painterTester.addLabel('01', 111.0, 42.7, 159.0, 90.7);
    painterTester.addLabel('02', 129.3, 61.0, 177.3, 109.0);
    painterTester.addLabel('03', 136.0, 86.0, 184.0, 134.0);
    painterTester.addLabel('04', 129.3, 111.0, 177.3, 159.0);
    painterTester.addLabel('05', 111.0, 129.3, 159.0, 177.3);
    painterTester.addLabel('06', 86.0, 136.0, 134.0, 184.0);
    painterTester.addLabel('07', 61.0, 129.3, 109.0, 177.3);
    painterTester.addLabel('08', 42.7, 111.0, 90.7, 159.0);
    painterTester.addLabel('09', 36.0, 86.0, 84.0, 134.0);
    painterTester.addLabel('10', 42.7, 61.0, 90.7, 109.0);
    painterTester.addLabel('11', 61.0, 42.7, 109.0, 90.7);

    painterTester.assertExpectations();
    semantics.dispose();
  });

  testWidgets('provides semantics information for minutes', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    await mediaQueryBoilerplate(tester, true);
    await tester.tap(_minuteControl);
    await tester.pumpAndSettle();

    final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
    final CustomPainter dialPainter = dialPaint.painter;
    final _CustomPainterSemanticsTester painterTester = _CustomPainterSemanticsTester(tester, dialPainter, semantics);

    painterTester.addLabel('00', 86.0, 0.0, 134.0, 48.0);
    painterTester.addLabel('05', 129.0, 11.5, 177.0, 59.5);
    painterTester.addLabel('10', 160.5, 43.0, 208.5, 91.0);
    painterTester.addLabel('15', 172.0, 86.0, 220.0, 134.0);
    painterTester.addLabel('20', 160.5, 129.0, 208.5, 177.0);
    painterTester.addLabel('25', 129.0, 160.5, 177.0, 208.5);
    painterTester.addLabel('30', 86.0, 172.0, 134.0, 220.0);
    painterTester.addLabel('35', 43.0, 160.5, 91.0, 208.5);
    painterTester.addLabel('40', 11.5, 129.0, 59.5, 177.0);
    painterTester.addLabel('45', 0.0, 86.0, 48.0, 134.0);
    painterTester.addLabel('50', 11.5, 43.0, 59.5, 91.0);
    painterTester.addLabel('55', 43.0, 11.5, 91.0, 59.5);

    painterTester.assertExpectations();
    semantics.dispose();
  });

  testWidgets('picks the right dial ring from widget configuration', (WidgetTester tester) async {
    await mediaQueryBoilerplate(tester, true, initialTime: const TimeOfDay(hour: 12, minute: 0));
    dynamic dialPaint = tester.widget(findDialPaint);
    expect('${dialPaint.painter.activeRing}', '_DialRing.inner');

    await tester.pumpWidget(Container()); // make sure previous state isn't reused

    await mediaQueryBoilerplate(tester, true, initialTime: const TimeOfDay(hour: 0, minute: 0));
    dialPaint = tester.widget(findDialPaint);
    expect('${dialPaint.painter.activeRing}', '_DialRing.outer');
  });

  testWidgets('can increment and decrement hours', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async {
      final SemanticsNode elevenHours = semantics.nodesWith(
        value: initialValue,
        ancestor: tester.renderObject(_hourControl).debugSemantics,
      ).single;
      tester.binding.pipelineOwner.semanticsOwner.performAction(elevenHours.id, action);
      await tester.pumpAndSettle();
      expect(
        find.descendant(of: _hourControl, matching: find.text(finalValue)),
        findsOneWidget,
      );
    }

    // 12-hour format
    await mediaQueryBoilerplate(tester, false, initialTime: const TimeOfDay(hour: 11, minute: 0));
    await actAndExpect(
      initialValue: '11',
      action: SemanticsAction.increase,
      finalValue: '12',
    );
    await actAndExpect(
      initialValue: '12',
      action: SemanticsAction.increase,
      finalValue: '1',
    );

    // Ensure we preserve day period as we roll over.
    final dynamic pickerState = tester.state(_timePickerDialog);
    expect(pickerState.selectedTime, const TimeOfDay(hour: 1, minute: 0));

    await actAndExpect(
      initialValue: '1',
      action: SemanticsAction.decrease,
      finalValue: '12',
    );
    await tester.pumpWidget(Container()); // clear old boilerplate

    // 24-hour format
    await mediaQueryBoilerplate(tester, true, initialTime: const TimeOfDay(hour: 23, minute: 0));
    await actAndExpect(
      initialValue: '23',
      action: SemanticsAction.increase,
      finalValue: '00',
    );
    await actAndExpect(
      initialValue: '00',
      action: SemanticsAction.increase,
      finalValue: '01',
    );
    await actAndExpect(
      initialValue: '01',
      action: SemanticsAction.decrease,
      finalValue: '00',
    );
    await actAndExpect(
      initialValue: '00',
      action: SemanticsAction.decrease,
      finalValue: '23',
    );

    semantics.dispose();
  });

  testWidgets('can increment and decrement minutes', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    Future<void> actAndExpect({ String initialValue, SemanticsAction action, String finalValue }) async {
      final SemanticsNode elevenHours = semantics.nodesWith(
        value: initialValue,
        ancestor: tester.renderObject(_minuteControl).debugSemantics,
      ).single;
      tester.binding.pipelineOwner.semanticsOwner.performAction(elevenHours.id, action);
      await tester.pumpAndSettle();
      expect(
        find.descendant(of: _minuteControl, matching: find.text(finalValue)),
        findsOneWidget,
      );
    }

    await mediaQueryBoilerplate(tester, false, initialTime: const TimeOfDay(hour: 11, minute: 58));
    await actAndExpect(
      initialValue: '58',
      action: SemanticsAction.increase,
      finalValue: '59',
    );
    await actAndExpect(
      initialValue: '59',
      action: SemanticsAction.increase,
      finalValue: '00',
    );

    // Ensure we preserve hour period as we roll over.
    final dynamic pickerState = tester.state(_timePickerDialog);
    expect(pickerState.selectedTime, const TimeOfDay(hour: 11, minute: 0));

    await actAndExpect(
      initialValue: '00',
      action: SemanticsAction.decrease,
      finalValue: '59',
    );
    await actAndExpect(
      initialValue: '59',
      action: SemanticsAction.decrease,
      finalValue: '58',
    );

    semantics.dispose();
  });

  testWidgets('header touch regions are large enough', (WidgetTester tester) async {
    await mediaQueryBoilerplate(tester, false);

    final Size amSize = tester.getSize(find.ancestor(
      of: find.text('AM'),
      matching: find.byType(InkWell),
    ));
    expect(amSize.width, greaterThanOrEqualTo(48.0));
    expect(amSize.height, greaterThanOrEqualTo(48.0));

    final Size pmSize = tester.getSize(find.ancestor(
      of: find.text('PM'),
      matching: find.byType(InkWell),
    ));
    expect(pmSize.width, greaterThanOrEqualTo(48.0));
    expect(pmSize.height, greaterThanOrEqualTo(48.0));

    final Size hourSize = tester.getSize(find.ancestor(
      of: find.text('7'),
      matching: find.byType(InkWell),
    ));
    expect(hourSize.width, greaterThanOrEqualTo(48.0));
    expect(hourSize.height, greaterThanOrEqualTo(48.0));

    final Size minuteSize = tester.getSize(find.ancestor(
      of: find.text('00'),
      matching: find.byType(InkWell),
    ));
    expect(minuteSize.width, greaterThanOrEqualTo(48.0));
    expect(minuteSize.height, greaterThanOrEqualTo(48.0));
  });

  testWidgets('builder parameter', (WidgetTester tester) async {
    Widget buildFrame(TextDirection textDirection) {
      return MaterialApp(
        home: Material(
          child: Center(
            child: Builder(
              builder: (BuildContext context) {
                return RaisedButton(
                  child: const Text('X'),
                  onPressed: () {
                    showTimePicker(
                      context: context,
                      initialTime: const TimeOfDay(hour: 7, minute: 0),
                      builder: (BuildContext context, Widget child) {
                        return Directionality(
                          textDirection: textDirection,
                          child: child,
                        );
                      },
                    );
                  },
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(TextDirection.ltr));
    await tester.tap(find.text('X'));
    await tester.pumpAndSettle();
    final double ltrOkRight = tester.getBottomRight(find.text('OK')).dx;

    await tester.tap(find.text('OK')); // dismiss the dialog
    await tester.pumpAndSettle();

    await tester.pumpWidget(buildFrame(TextDirection.rtl));
    await tester.tap(find.text('X'));
    await tester.pumpAndSettle();

    // Verify that the time picker is being laid out RTL.
    // We expect the left edge of the 'OK' button in the RTL
    // layout to match the gap between right edge of the 'OK'
    // button and the right edge of the 800 wide window.
    expect(tester.getBottomLeft(find.text('OK')).dx, 800 - ltrOkRight);
  });
}

final Finder findDialPaint = find.descendant(
  of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_Dial'),
  matching: find.byWidgetPredicate((Widget w) => w is CustomPaint),
);

class _SemanticsNodeExpectation {
  _SemanticsNodeExpectation(this.label, this.left, this.top, this.right, this.bottom);

  final String label;
  final double left;
  final double top;
  final double right;
  final double bottom;
}

class _CustomPainterSemanticsTester {
  _CustomPainterSemanticsTester(this.tester, this.painter, this.semantics);

  final WidgetTester tester;
  final CustomPainter painter;
  final SemanticsTester semantics;
  final PaintPattern expectedLabels = paints;
  final List<_SemanticsNodeExpectation> expectedNodes = <_SemanticsNodeExpectation>[];

  void addLabel(String label, double left, double top, double right, double bottom) {
    expectedNodes.add(_SemanticsNodeExpectation(label, left, top, right, bottom));
  }

  void assertExpectations() {
    final TestRecordingCanvas canvasRecording = TestRecordingCanvas();
    painter.paint(canvasRecording, const Size(220.0, 220.0));
    final List<ui.Paragraph> paragraphs = canvasRecording.invocations
      .where((RecordedInvocation recordedInvocation) {
        return recordedInvocation.invocation.memberName == #drawParagraph;
      })
      .map<ui.Paragraph>((RecordedInvocation recordedInvocation) {
        return recordedInvocation.invocation.positionalArguments.first;
      })
      .toList();

    final PaintPattern expectedLabels = paints;
    int i = 0;

    for (_SemanticsNodeExpectation expectation in expectedNodes) {
      expect(semantics, includesNodeWith(value: expectation.label));
      final Iterable<SemanticsNode> dialLabelNodes = semantics
          .nodesWith(value: expectation.label)
          .where((SemanticsNode node) => node.tags?.contains(const SemanticsTag('dial-label')) ?? false);
      expect(dialLabelNodes, hasLength(1), reason: 'Expected exactly one label ${expectation.label}');
      final Rect rect = Rect.fromLTRB(expectation.left, expectation.top, expectation.right, expectation.bottom);
      expect(dialLabelNodes.single.rect, within(distance: 1.0, from: rect),
        reason: 'This is checking the node rectangle for label ${expectation.label}');

      final ui.Paragraph paragraph = paragraphs[i++];

      // The label text paragraph and the semantics node share the same center,
      // but have different sizes.
      final Offset center = dialLabelNodes.single.rect.center;
      final Offset topLeft = center.translate(
        -paragraph.width / 2.0,
        -paragraph.height / 2.0,
      );

      expectedLabels.paragraph(
        paragraph: paragraph,
        offset: within<Offset>(distance: 1.0, from: topLeft),
      );
    }
    expect(tester.renderObject(findDialPaint), expectedLabels);
  }
}
