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

// This file is for testings that require a `LiveTestWidgetsFlutterBinding`
void main() {
  final LiveTestWidgetsFlutterBinding binding = LiveTestWidgetsFlutterBinding();
  testWidgets('Input PointerAddedEvent', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: Text('Test')));
    await tester.pump();
    final TestGesture gesture = await tester.createGesture();
    // This mimics the start of a gesture as seen on a device, where inputs
    // starts with a PointerAddedEvent.
    await gesture.addPointer();
    // The expected result of the test is not to trigger any assert.
  });

  testWidgets('Input PointerHoverEvent', (WidgetTester tester) async {
    PointerHoverEvent? hoverEvent;
    await tester.pumpWidget(MaterialApp(home: MouseRegion(
      child: const Text('Test'),
      onHover: (PointerHoverEvent event) {
        hoverEvent = event;
      },
    )));
    await tester.pump();
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    final Offset location = tester.getCenter(find.text('Test'));
    // for mouse input without a down event, moveTo generates a hover event
    await gesture.moveTo(location);
    expect(hoverEvent, isNotNull);
    expect(hoverEvent!.position, location);
  });

  testWidgets('hitTesting works when using setSurfaceSize', (WidgetTester tester) async {
    int invocations = 0;
    await tester.pumpWidget(
      MaterialApp(
        home: Center(
          child: GestureDetector(
            onTap: () {
              invocations++;
            },
            child: const Text('Test'),
          ),
        ),
      ),
    );

    await tester.tap(find.byType(Text));
    await tester.pump();
    expect(invocations, 1);

    await tester.binding.setSurfaceSize(const Size(200, 300));
    await tester.pump();
    await tester.tap(find.byType(Text));
    await tester.pump();
    expect(invocations, 2);

    await tester.binding.setSurfaceSize(null);
    await tester.pump();
    await tester.tap(find.byType(Text));
    await tester.pump();
    expect(invocations, 3);
  });

  testWidgets('setSurfaceSize works', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: Center(child: Text('Test'))));

    final Size windowCenter = tester.binding.window.physicalSize /
        tester.binding.window.devicePixelRatio /
        2;
    final double windowCenterX = windowCenter.width;
    final double windowCenterY = windowCenter.height;

    Offset widgetCenter = tester.getRect(find.byType(Text)).center;
    expect(widgetCenter.dx, windowCenterX);
    expect(widgetCenter.dy, windowCenterY);

    await tester.binding.setSurfaceSize(const Size(200, 300));
    await tester.pump();
    widgetCenter = tester.getRect(find.byType(Text)).center;
    expect(widgetCenter.dx, 100);
    expect(widgetCenter.dy, 150);

    await tester.binding.setSurfaceSize(null);
    await tester.pump();
    widgetCenter = tester.getRect(find.byType(Text)).center;
    expect(widgetCenter.dx, windowCenterX);
    expect(widgetCenter.dy, windowCenterY);
  });

  testWidgets("reassembleApplication doesn't get stuck", (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/79150

    await expectLater(tester.binding.reassembleApplication(), completes);
  }, timeout: const Timeout(Duration(seconds: 30)));

  testWidgets('shouldPropagateDevicePointerEvents can override events from ${TestBindingEventSource.device}', (WidgetTester tester) async {
    binding.shouldPropagateDevicePointerEvents = true;

    await tester.pumpWidget(_ShowNumTaps());

    final Offset position = tester.getCenter(find.text('0'));

    // Simulates a real device tap.
    //
    // `handlePointerEventForSource defaults to sending events using
    // TestBindingEventSource.device. This will not be forwarded to the actual
    // gesture handlers, unless `shouldPropagateDevicePointerEvents` is true.
    binding.handlePointerEventForSource(
      PointerDownEvent(position: position),
    );
    binding.handlePointerEventForSource(
      PointerUpEvent(position: position),
    );

    await tester.pump();

    expect(find.text('1'), findsOneWidget);

    // Reset the value, otherwise the test will fail when it checks that this
    // has not been changed as an invariant.
    binding.shouldPropagateDevicePointerEvents = false;
  });
}

/// A widget that shows the number of times it has been tapped.
class _ShowNumTaps extends StatefulWidget {
  @override
  _ShowNumTapsState createState() => _ShowNumTapsState();
}

class _ShowNumTapsState extends State<_ShowNumTaps> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _counter++;
        });
      },
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: Text(_counter.toString()),
      ),
    );
  }
}
