// 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 '../flutter_test_alternative.dart';
import 'gesture_tester.dart';

// Down/move/up pair 1: normal tap sequence
const PointerDownEvent down = PointerDownEvent(
  pointer: 5,
  position: Offset(10, 10),
);

const PointerUpEvent up = PointerUpEvent(
  pointer: 5,
  position: Offset(11, 9),
);

const PointerMoveEvent move = PointerMoveEvent(
  pointer: 5,
  position: Offset(100, 200),
);

// Down/up pair 2: normal tap sequence far away from pair 1
const PointerDownEvent down2 = PointerDownEvent(
  pointer: 6,
  position: Offset(10, 10),
);

const PointerUpEvent up2 = PointerUpEvent(
  pointer: 6,
  position: Offset(11, 9),
);

// Down/up pair 3: tap sequence with secondary button
const PointerDownEvent down3 = PointerDownEvent(
  pointer: 7,
  position: Offset(30, 30),
  buttons: kSecondaryButton,
);

const PointerUpEvent up3 = PointerUpEvent(
  pointer: 7,
  position: Offset(31, 29),
);

void main() {
  setUp(ensureGestureBinding);

  group('Long press', () {
    LongPressGestureRecognizer longPress;
    bool longPressDown;
    bool longPressUp;

    setUp(() {
      longPress = LongPressGestureRecognizer();
      longPressDown = false;
      longPress.onLongPress = () {
        longPressDown = true;
      };
      longPressUp = false;
      longPress.onLongPressUp = () {
        longPressUp = true;
      };
    });

    testGesture('Should recognize long press', (GestureTester tester) {
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 700));
      expect(longPressDown, isTrue);

      longPress.dispose();
    });

    testGesture('Should recognize long press with altered duration', (GestureTester tester) {
      longPress = LongPressGestureRecognizer(duration: const Duration(milliseconds: 100));
      longPressDown = false;
      longPress.onLongPress = () {
        longPressDown = true;
      };
      longPressUp = false;
      longPress.onLongPressUp = () {
        longPressUp = true;
      };
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 50));
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 50));
      expect(longPressDown, isTrue);

      longPress.dispose();
    });

    testGesture('Up cancels long press', (GestureTester tester) {
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressDown, isFalse);
      tester.route(up);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(seconds: 1));
      expect(longPressDown, isFalse);

      longPress.dispose();
    });

    testGesture('Moving before accept cancels', (GestureTester tester) {
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressDown, isFalse);
      tester.route(move);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(seconds: 1));
      tester.route(up);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressDown, isFalse);
      expect(longPressUp, isFalse);

      longPress.dispose();
    });

    testGesture('Moving after accept is ok', (GestureTester tester) {
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(seconds: 1));
      expect(longPressDown, isTrue);
      tester.route(move);
      tester.route(up);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressDown, isTrue);
      expect(longPressUp, isTrue);

      longPress.dispose();
    });

    testGesture('Should recognize both tap down and long press', (GestureTester tester) {
      final TapGestureRecognizer tap = TapGestureRecognizer();

      bool tapDownRecognized = false;
      tap.onTapDown = (_) {
        tapDownRecognized = true;
      };

      tap.addPointer(down);
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(tapDownRecognized, isFalse);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(tapDownRecognized, isFalse);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(tapDownRecognized, isTrue);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 700));
      expect(tapDownRecognized, isTrue);
      expect(longPressDown, isTrue);

      tap.dispose();
      longPress.dispose();
    });

    testGesture('Drag start delayed by microtask', (GestureTester tester) {
      final HorizontalDragGestureRecognizer drag = HorizontalDragGestureRecognizer();

      bool isDangerousStack = false;

      bool dragStartRecognized = false;
      drag.onStart = (DragStartDetails details) {
        expect(isDangerousStack, isFalse);
        dragStartRecognized = true;
      };

      drag.addPointer(down);
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(dragStartRecognized, isFalse);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(dragStartRecognized, isFalse);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(dragStartRecognized, isFalse);
      expect(longPressDown, isFalse);
      isDangerousStack = true;
      longPress.dispose();
      isDangerousStack = false;
      expect(dragStartRecognized, isFalse);
      expect(longPressDown, isFalse);
      tester.async.flushMicrotasks();
      expect(dragStartRecognized, isTrue);
      expect(longPressDown, isFalse);
      drag.dispose();
    });

    testGesture('Should recognize long press up', (GestureTester tester) {
      bool longPressUpRecognized = false;
      longPress.onLongPressUp = () {
        longPressUpRecognized = true;
      };

      longPress.addPointer(down);
      tester.closeArena(5);
      expect(longPressUpRecognized, isFalse);
      tester.route(down); // kLongPressTimeout = 500;
      expect(longPressUpRecognized, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressUpRecognized, isFalse);
      tester.async.elapse(const Duration(milliseconds: 700));
      tester.route(up);
      expect(longPressUpRecognized, isTrue);

      longPress.dispose();
    });

    testGesture('Should not recognize long press with more than one buttons', (GestureTester tester) {
      longPress.addPointer(const PointerDownEvent(
        pointer: 5,
        kind: PointerDeviceKind.mouse,
        buttons: kSecondaryMouseButton | kMiddleMouseButton,
        position: Offset(10, 10),
      ));
      tester.closeArena(5);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 1000));
      expect(longPressDown, isFalse);
      tester.route(up);
      expect(longPressUp, isFalse);

      longPress.dispose();
    });

    testGesture('Should cancel long press when buttons change before acceptance', (GestureTester tester) {
      longPress.addPointer(down);
      tester.closeArena(5);
      expect(longPressDown, isFalse);
      tester.route(down);
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressDown, isFalse);
      tester.route(const PointerMoveEvent(
        pointer: 5,
        kind: PointerDeviceKind.mouse,
        buttons: kMiddleMouseButton,
        position: Offset(10, 10),
      ));
      expect(longPressDown, isFalse);
      tester.async.elapse(const Duration(milliseconds: 700));
      expect(longPressDown, isFalse);
      tester.route(up);
      expect(longPressUp, isFalse);

      longPress.dispose();
    });
  });

  group('long press drag', () {
    LongPressGestureRecognizer longPressDrag;
    bool longPressStart;
    bool longPressUp;
    Offset longPressDragUpdate;

    setUp(() {
      longPressDrag = LongPressGestureRecognizer();
      longPressStart = false;
      longPressDrag.onLongPressStart = (LongPressStartDetails details) {
        longPressStart = true;
      };
      longPressUp = false;
      longPressDrag.onLongPressEnd = (LongPressEndDetails details) {
        longPressUp = true;
      };
      longPressDragUpdate = null;
      longPressDrag.onLongPressMoveUpdate = (LongPressMoveUpdateDetails details) {
        longPressDragUpdate = details.globalPosition;
      };
    });

    testGesture('Should recognize long press down', (GestureTester tester) {
      longPressDrag.addPointer(down);
      tester.closeArena(5);
      expect(longPressStart, isFalse);
      tester.route(down);
      expect(longPressStart, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressStart, isFalse);
      tester.async.elapse(const Duration(milliseconds: 700));
      expect(longPressStart, isTrue);

      longPressDrag.dispose();
    });

    testGesture('Short up cancels long press', (GestureTester tester) {
      longPressDrag.addPointer(down);
      tester.closeArena(5);
      expect(longPressStart, isFalse);
      tester.route(down);
      expect(longPressStart, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressStart, isFalse);
      tester.route(up);
      expect(longPressStart, isFalse);
      tester.async.elapse(const Duration(seconds: 1));
      expect(longPressStart, isFalse);

      longPressDrag.dispose();
    });

    testGesture('Moving before accept cancels', (GestureTester tester) {
      longPressDrag.addPointer(down);
      tester.closeArena(5);
      expect(longPressStart, isFalse);
      tester.route(down);
      expect(longPressStart, isFalse);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressStart, isFalse);
      tester.route(move);
      expect(longPressStart, isFalse);
      tester.async.elapse(const Duration(seconds: 1));
      tester.route(up);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressStart, isFalse);
      expect(longPressUp, isFalse);

      longPressDrag.dispose();
    });

    testGesture('Moving after accept does not cancel', (GestureTester tester) {
      longPressDrag.addPointer(down);
      tester.closeArena(5);
      expect(longPressStart, isFalse);
      tester.route(down);
      expect(longPressStart, isFalse);
      tester.async.elapse(const Duration(seconds: 1));
      expect(longPressStart, isTrue);
      tester.route(move);
      expect(longPressDragUpdate, const Offset(100, 200));
      tester.route(up);
      tester.async.elapse(const Duration(milliseconds: 300));
      expect(longPressStart, isTrue);
      expect(longPressUp, isTrue);

      longPressDrag.dispose();
    });
  });

  group('Enforce consistent-button restriction:', () {
    // In sequence between `down` and `up` but with buttons changed
    const PointerMoveEvent moveR = PointerMoveEvent(
      pointer: 5,
      buttons: kSecondaryButton,
      position: Offset(10, 10),
    );

    final List<String> recognized = <String>[];

    LongPressGestureRecognizer longPress;

    setUp(() {
      longPress = LongPressGestureRecognizer()
        ..onLongPressStart = (LongPressStartDetails details) {
          recognized.add('start');
        }
        ..onLongPressEnd = (LongPressEndDetails details) {
          recognized.add('end');
        };
    });

    tearDown(() {
      longPress.dispose();
      recognized.clear();
    });

    testGesture('Should cancel long press when buttons change before acceptance', (GestureTester tester) {
      // First press
      longPress.addPointer(down);
      tester.closeArena(down.pointer);
      tester.route(down);
      tester.async.elapse(const Duration(milliseconds: 300));
      tester.route(moveR);
      expect(recognized, <String>[]);
      tester.async.elapse(const Duration(milliseconds: 700));
      tester.route(up);
      expect(recognized, <String>[]);
    });

    testGesture('Buttons change before acceptance should not prevent the next long press', (GestureTester tester) {
      // First press
      longPress.addPointer(down);
      tester.closeArena(down.pointer);
      tester.route(down);
      tester.async.elapse(const Duration(milliseconds: 300));
      tester.route(moveR);
      tester.async.elapse(const Duration(milliseconds: 700));
      tester.route(up);
      recognized.clear();

      // Second press
      longPress.addPointer(down2);
      tester.closeArena(down2.pointer);
      tester.route(down2);
      tester.async.elapse(const Duration(milliseconds: 1000));
      expect(recognized, <String>['start']);
      recognized.clear();

      tester.route(up2);
      expect(recognized, <String>['end']);
    });

    testGesture('Should cancel long press when buttons change after acceptance', (GestureTester tester) {
      // First press
      longPress.addPointer(down);
      tester.closeArena(down.pointer);
      tester.route(down);
      tester.async.elapse(const Duration(milliseconds: 1000));
      expect(recognized, <String>['start']);
      recognized.clear();

      tester.route(moveR);
      expect(recognized, <String>[]);
      tester.route(up);
      expect(recognized, <String>[]);
    });

    testGesture('Buttons change after acceptance should not prevent the next long press', (GestureTester tester) {
      // First press
      longPress.addPointer(down);
      tester.closeArena(down.pointer);
      tester.route(down);
      tester.async.elapse(const Duration(milliseconds: 1000));
      tester.route(moveR);
      tester.route(up);
      recognized.clear();

      // Second press
      longPress.addPointer(down2);
      tester.closeArena(down2.pointer);
      tester.route(down2);
      tester.async.elapse(const Duration(milliseconds: 1000));
      expect(recognized, <String>['start']);
      recognized.clear();

      tester.route(up2);
      expect(recognized, <String>['end']);
    });
  });

  testGesture('Can filter long press based on device kind', (GestureTester tester) {
    final LongPressGestureRecognizer mouseLongPress = LongPressGestureRecognizer(kind: PointerDeviceKind.mouse);

    bool mouseLongPressDown = false;
    mouseLongPress.onLongPress = () {
      mouseLongPressDown = true;
    };

    const PointerDownEvent mouseDown = PointerDownEvent(
      pointer: 5,
      position: Offset(10, 10),
      kind: PointerDeviceKind.mouse,
    );
    const PointerDownEvent touchDown = PointerDownEvent(
      pointer: 5,
      position: Offset(10, 10),
      kind: PointerDeviceKind.touch,
    );

    // Touch events shouldn't be recognized.
    mouseLongPress.addPointer(touchDown);
    tester.closeArena(5);
    expect(mouseLongPressDown, isFalse);
    tester.route(touchDown);
    expect(mouseLongPressDown, isFalse);
    tester.async.elapse(const Duration(seconds: 2));
    expect(mouseLongPressDown, isFalse);

    // Mouse events are still recognized.
    mouseLongPress.addPointer(mouseDown);
    tester.closeArena(5);
    expect(mouseLongPressDown, isFalse);
    tester.route(mouseDown);
    expect(mouseLongPressDown, isFalse);
    tester.async.elapse(const Duration(seconds: 2));
    expect(mouseLongPressDown, isTrue);

    mouseLongPress.dispose();
  });

  group('Recognizers listening on different buttons do not form competition:', () {
    // This test is assisted by tap recognizers. If a tap gesture has
    // no competing recognizers, a pointer down event triggers its onTapDown
    // immediately; if there are competitors, onTapDown is triggered after a
    // timeout.
    // The following tests make sure that long press recognizers do not form
    // competition with a tap gesture recognizer listening on a different button.

    final List<String> recognized = <String>[];
    TapGestureRecognizer tapPrimary;
    TapGestureRecognizer tapSecondary;
    LongPressGestureRecognizer longPress;
    setUp(() {
      tapPrimary = TapGestureRecognizer()
        ..onTapDown = (TapDownDetails details) {
          recognized.add('tapPrimary');
        };
      tapSecondary = TapGestureRecognizer()
        ..onSecondaryTapDown = (TapDownDetails details) {
          recognized.add('tapSecondary');
        };
      longPress = LongPressGestureRecognizer()
        ..onLongPressStart = (_) {
          recognized.add('longPress');
        };
    });

    tearDown(() {
      recognized.clear();
      tapPrimary.dispose();
      tapSecondary.dispose();
      longPress.dispose();
    });

    testGesture('A primary long press recognizer does not form competition with a secondary tap recognizer', (GestureTester tester) {
      longPress.addPointer(down3);
      tapSecondary.addPointer(down3);
      tester.closeArena(down3.pointer);

      tester.route(down3);
      expect(recognized, <String>['tapSecondary']);
    });

    testGesture('A primary long press recognizer forms competition with a primary tap recognizer', (GestureTester tester) {
      longPress.addPointer(down);
      tapPrimary.addPointer(down);
      tester.closeArena(down.pointer);

      tester.route(down);
      expect(recognized, <String>[]);

      tester.route(up);
      expect(recognized, <String>['tapPrimary']);
    });
  });

  testGesture('A secondary long press should not trigger primary', (GestureTester tester) {
    final List<String> recognized = <String>[];
    final LongPressGestureRecognizer longPress = LongPressGestureRecognizer()
      ..onLongPressStart = (LongPressStartDetails details) {
        recognized.add('primaryStart');
      }
      ..onLongPress = () {
        recognized.add('primary');
      }
      ..onLongPressMoveUpdate = (LongPressMoveUpdateDetails details) {
        recognized.add('primaryUpdate');
      }
      ..onLongPressEnd = (LongPressEndDetails details) {
        recognized.add('primaryEnd');
      }
      ..onLongPressUp = () {
        recognized.add('primaryUp');
      };

    const PointerDownEvent down2 = PointerDownEvent(
      pointer: 2,
      buttons: kSecondaryButton,
      position: Offset(30.0, 30.0),
    );

    const PointerMoveEvent move2 = PointerMoveEvent(
      pointer: 2,
      buttons: kSecondaryButton,
      position: Offset(100, 200),
    );

    const PointerUpEvent up2 = PointerUpEvent(
      pointer: 2,
      position: Offset(100, 201),
    );

    longPress.addPointer(down2);
    tester.closeArena(2);
    tester.route(down2);
    tester.async.elapse(const Duration(milliseconds: 700));
    tester.route(move2);
    tester.route(up2);
    expect(recognized, <String>[]);
    longPress.dispose();
    recognized.clear();
  });
}
