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

// @dart = 2.8

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),
);

// Down/up pair 4: tap sequence with tertiary button
const PointerDownEvent down4 = PointerDownEvent(
  pointer: 8,
  position: Offset(42, 24),
  buttons: kTertiaryButton,
);

const PointerUpEvent up4 = PointerUpEvent(
  pointer: 8,
  position: Offset(43, 23),
);

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 | kTertiaryButton,
        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: kTertiaryButton,
        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();
  });

  testGesture('A tertiary long press should not trigger primary or secondary', (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');
      }
      ..onSecondaryLongPressStart = (LongPressStartDetails details) {
        recognized.add('secondaryStart');
      }
      ..onSecondaryLongPress = () {
        recognized.add('secondary');
      }
      ..onSecondaryLongPressMoveUpdate = (LongPressMoveUpdateDetails details) {
        recognized.add('secondaryUpdate');
      }
      ..onSecondaryLongPressEnd = (LongPressEndDetails details) {
        recognized.add('secondaryEnd');
      }
      ..onSecondaryLongPressUp = () {
        recognized.add('secondaryUp');
      };

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

    const PointerMoveEvent move2 = PointerMoveEvent(
      pointer: 2,
      buttons: kTertiaryButton,
      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();
  });
}
