// 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_test/flutter_test.dart';

import 'gesture_tester.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  test('acceptGesture tolerates a null lastPendingEventTimestamp', () {
    // Regression test for https://github.com/flutter/flutter/issues/112403
    // and b/249091367
    final DragGestureRecognizer recognizer = VerticalDragGestureRecognizer();
    const PointerDownEvent event = PointerDownEvent(timeStamp: Duration(days: 10));

    expect(recognizer.debugLastPendingEventTimestamp, null);

    recognizer.addAllowedPointer(event);
    expect(recognizer.debugLastPendingEventTimestamp, event.timeStamp);

    // Normal case: acceptGesture called and we have a last timestamp set.
    recognizer.acceptGesture(event.pointer);
    expect(recognizer.debugLastPendingEventTimestamp, null);

    // Reject the gesture to reset state and allow accepting it again.
    recognizer.rejectGesture(event.pointer);
    expect(recognizer.debugLastPendingEventTimestamp, null);

    // Not entirely clear how this can happen, but the bugs mentioned above show
    // we can end up in this state empirically.
    recognizer.acceptGesture(event.pointer);
    expect(recognizer.debugLastPendingEventTimestamp, null);
  });

  testGesture('do not crash on up event for a pending pointer after winning arena for another pointer', (GestureTester tester) {
    // Regression test for https://github.com/flutter/flutter/issues/75061.

    final VerticalDragGestureRecognizer v = VerticalDragGestureRecognizer()
      ..onStart = (_) { };
    addTearDown(v.dispose);
    final HorizontalDragGestureRecognizer h = HorizontalDragGestureRecognizer()
      ..onStart = (_) { };
    addTearDown(h.dispose);

    const PointerDownEvent down90 = PointerDownEvent(
      pointer: 90,
      position: Offset(10.0, 10.0),
    );

    const PointerUpEvent up90 = PointerUpEvent(
      pointer: 90,
      position: Offset(10.0, 10.0),
    );

    const PointerDownEvent down91 = PointerDownEvent(
      pointer: 91,
      position: Offset(20.0, 20.0),
    );

    const PointerUpEvent up91 = PointerUpEvent(
      pointer: 91,
      position: Offset(20.0, 20.0),
    );

    v.addPointer(down90);
    GestureBinding.instance.gestureArena.close(90);
    h.addPointer(down91);
    v.addPointer(down91);
    GestureBinding.instance.gestureArena.close(91);
    tester.async.flushMicrotasks();

    GestureBinding.instance.handleEvent(up90, HitTestEntry(MockHitTestTarget()));
    GestureBinding.instance.handleEvent(up91, HitTestEntry(MockHitTestTarget()));
  });

  testGesture('DragGestureRecognizer should not dispatch drag callbacks when it wins the arena if onlyAcceptDragOnThreshold is true and the threshold has not been met', (GestureTester tester) {
    final VerticalDragGestureRecognizer verticalDrag = VerticalDragGestureRecognizer();
    final List<String> dragCallbacks = <String>[];
    verticalDrag
      ..onlyAcceptDragOnThreshold = true
      ..onStart = (DragStartDetails details) {
        dragCallbacks.add('onStart');
      }
      ..onUpdate = (DragUpdateDetails details) {
        dragCallbacks.add('onUpdate');
      }
      ..onEnd = (DragEndDetails details) {
        dragCallbacks.add('onEnd');
      };

    const PointerDownEvent down1 = PointerDownEvent(
      pointer: 6,
      position: Offset(10.0, 10.0),
    );

    const PointerUpEvent up1 = PointerUpEvent(
      pointer: 6,
      position: Offset(10.0, 10.0),
    );

    verticalDrag.addPointer(down1);
    tester.closeArena(down1.pointer);
    tester.route(down1);
    tester.route(up1);
    expect(dragCallbacks.isEmpty, true);
    verticalDrag.dispose();
    dragCallbacks.clear();
  });

  testGesture('DragGestureRecognizer should dispatch drag callbacks when it wins the arena if onlyAcceptDragOnThreshold is false and the threshold has not been met', (GestureTester tester) {
    final VerticalDragGestureRecognizer verticalDrag = VerticalDragGestureRecognizer();
    final List<String> dragCallbacks = <String>[];
    verticalDrag
      ..onlyAcceptDragOnThreshold = false
      ..onStart = (DragStartDetails details) {
        dragCallbacks.add('onStart');
      }
      ..onUpdate = (DragUpdateDetails details) {
        dragCallbacks.add('onUpdate');
      }
      ..onEnd = (DragEndDetails details) {
        dragCallbacks.add('onEnd');
      };

    const PointerDownEvent down1 = PointerDownEvent(
      pointer: 6,
      position: Offset(10.0, 10.0),
    );

    const PointerUpEvent up1 = PointerUpEvent(
      pointer: 6,
      position: Offset(10.0, 10.0),
    );

    verticalDrag.addPointer(down1);
    tester.closeArena(down1.pointer);
    tester.route(down1);
    tester.route(up1);
    expect(dragCallbacks.isEmpty, false);
    expect(dragCallbacks, <String>['onStart', 'onEnd']);
    verticalDrag.dispose();
    dragCallbacks.clear();
  });

  group('Recognizers on different button filters:', () {
    final List<String> recognized = <String>[];
    late HorizontalDragGestureRecognizer primaryRecognizer;
    late HorizontalDragGestureRecognizer secondaryRecognizer;
    setUp(() {
      primaryRecognizer = HorizontalDragGestureRecognizer(
          allowedButtonsFilter: (int buttons) => kPrimaryButton == buttons)
        ..onStart = (DragStartDetails details) {
          recognized.add('onStartPrimary');
        };
      secondaryRecognizer = HorizontalDragGestureRecognizer(
          allowedButtonsFilter: (int buttons) => kSecondaryButton == buttons)
        ..onStart = (DragStartDetails details) {
          recognized.add('onStartSecondary');
        };
    });

    tearDown(() {
      recognized.clear();
      primaryRecognizer.dispose();
      secondaryRecognizer.dispose();
    });

    testGesture('Primary button works', (GestureTester tester) {
      const PointerDownEvent down1 = PointerDownEvent(
        pointer: 6,
        position: Offset(10.0, 10.0),
      );

      primaryRecognizer.addPointer(down1);
      secondaryRecognizer.addPointer(down1);
      tester.closeArena(down1.pointer);
      tester.route(down1);
      expect(recognized, <String>['onStartPrimary']);
    });

    testGesture('Secondary button works', (GestureTester tester) {
      const PointerDownEvent down1 = PointerDownEvent(
        pointer: 6,
        position: Offset(10.0, 10.0),
        buttons: kSecondaryMouseButton,
      );

      primaryRecognizer.addPointer(down1);
      secondaryRecognizer.addPointer(down1);
      tester.closeArena(down1.pointer);
      tester.route(down1);
      expect(recognized, <String>['onStartSecondary']);
    });
  });
}

class MockHitTestTarget implements HitTestTarget {
  @override
  void handleEvent(PointerEvent event, HitTestEntry entry) { }
}
