// 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 'dart:ui' show VoidCallback;

import 'package:flutter/gestures.dart';
import 'package:flutter_test/flutter_test.dart';

import 'gesture_tester.dart';

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

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

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

// Down/move/up pair 2: tap sequence with a large move in the middle
const PointerDownEvent down2 = PointerDownEvent(
  pointer: 6,
  position: Offset(10, 10),
);

const PointerMoveEvent move2 = PointerMoveEvent(
  pointer: 6,
  position: Offset(100, 200),
);

const PointerUpEvent up2 = PointerUpEvent(
  pointer: 6,
  position: Offset(100, 200),
);

void main() {
  setUp(ensureGestureBinding);

  test('GestureRecognizer smoketest', () {
    final TestGestureRecognizer recognizer = TestGestureRecognizer(debugOwner: 0);
    expect(recognizer, hasAGoodToStringDeep);
  });

  test('OffsetPair', () {
    const OffsetPair offset1 = OffsetPair(
      local: Offset(10, 20),
      global: Offset(30, 40),
    );

    expect(offset1.local, const Offset(10, 20));
    expect(offset1.global, const Offset(30, 40));

    const OffsetPair offset2 = OffsetPair(
      local: Offset(50, 60),
      global: Offset(70, 80),
    );

    final OffsetPair sum = offset2 + offset1;
    expect(sum.local, const Offset(60, 80));
    expect(sum.global, const Offset(100, 120));

    final OffsetPair difference = offset2 - offset1;
    expect(difference.local, const Offset(40, 40));
    expect(difference.global, const Offset(40, 40));
  });

  testWidgets('EagerGestureRecognizer asserts when kind and supportedDevices are both set', (WidgetTester tester) async {
    expect(
      () {
        EagerGestureRecognizer(
            kind: PointerDeviceKind.touch,
            supportedDevices: <PointerDeviceKind>{ PointerDeviceKind.touch },
        );
      },
      throwsA(
        isA<AssertionError>().having((AssertionError error) => error.toString(),
        'description', contains('kind == null || supportedDevices == null')),
      ),
    );
  });

  group('PrimaryPointerGestureRecognizer', () {
    testGesture('cleans up state after winning arena', (GestureTester tester) {
      final List<String> resolutions = <String>[];
      final IndefiniteGestureRecognizer indefinite = IndefiniteGestureRecognizer();
      final TestPrimaryPointerGestureRecognizer<PointerUpEvent> accepting = TestPrimaryPointerGestureRecognizer<PointerUpEvent>(
        GestureDisposition.accepted,
        onAcceptGesture: () => resolutions.add('accepted'),
        onRejectGesture: () => resolutions.add('rejected'),
      );
      expect(accepting.state, GestureRecognizerState.ready);
      expect(accepting.primaryPointer, isNull);
      expect(accepting.initialPosition, isNull);
      expect(resolutions, <String>[]);

      indefinite.addPointer(down);
      accepting.addPointer(down);
      expect(accepting.state, GestureRecognizerState.possible);
      expect(accepting.primaryPointer, 5);
      expect(accepting.initialPosition!.global, down.position);
      expect(accepting.initialPosition!.local, down.localPosition);
      expect(resolutions, <String>[]);

      tester.closeArena(5);
      tester.async.flushMicrotasks();
      tester.route(down);
      tester.route(up);
      expect(accepting.state, GestureRecognizerState.ready);
      expect(accepting.primaryPointer, 5);
      expect(accepting.initialPosition, isNull);
      expect(resolutions, <String>['accepted']);
    });

    testGesture('cleans up state after losing arena', (GestureTester tester) {
      final List<String> resolutions = <String>[];
      final IndefiniteGestureRecognizer indefinite = IndefiniteGestureRecognizer();
      final TestPrimaryPointerGestureRecognizer<PointerMoveEvent> rejecting = TestPrimaryPointerGestureRecognizer<PointerMoveEvent>(
        GestureDisposition.rejected,
        onAcceptGesture: () => resolutions.add('accepted'),
        onRejectGesture: () => resolutions.add('rejected'),
      );
      expect(rejecting.state, GestureRecognizerState.ready);
      expect(rejecting.primaryPointer, isNull);
      expect(rejecting.initialPosition, isNull);
      expect(resolutions, <String>[]);

      indefinite.addPointer(down);
      rejecting.addPointer(down);
      expect(rejecting.state, GestureRecognizerState.possible);
      expect(rejecting.primaryPointer, 5);
      expect(rejecting.initialPosition!.global, down.position);
      expect(rejecting.initialPosition!.local, down.localPosition);
      expect(resolutions, <String>[]);

      tester.closeArena(5);
      tester.async.flushMicrotasks();
      tester.route(down);
      tester.route(move);
      expect(rejecting.state, GestureRecognizerState.defunct);
      expect(rejecting.primaryPointer, 5);
      expect(rejecting.initialPosition!.global, down.position);
      expect(rejecting.initialPosition!.local, down.localPosition);
      expect(resolutions, <String>['rejected']);

      tester.route(up);
      expect(rejecting.state, GestureRecognizerState.ready);
      expect(rejecting.primaryPointer, 5);
      expect(rejecting.initialPosition, isNull);
      expect(resolutions, <String>['rejected']);
    });

    testGesture('works properly when recycled', (GestureTester tester) {
      final List<String> resolutions = <String>[];
      final IndefiniteGestureRecognizer indefinite = IndefiniteGestureRecognizer();
      final TestPrimaryPointerGestureRecognizer<PointerUpEvent> accepting = TestPrimaryPointerGestureRecognizer<PointerUpEvent>(
        GestureDisposition.accepted,
        preAcceptSlopTolerance: 15,
        postAcceptSlopTolerance: 1000,
        onAcceptGesture: () => resolutions.add('accepted'),
        onRejectGesture: () => resolutions.add('rejected'),
      );

      // Send one complete pointer sequence
      indefinite.addPointer(down);
      accepting.addPointer(down);
      tester.closeArena(5);
      tester.async.flushMicrotasks();
      tester.route(down);
      tester.route(up);
      expect(resolutions, <String>['accepted']);
      resolutions.clear();

      // Send a follow-on sequence that breaks preAcceptSlopTolerance
      indefinite.addPointer(down2);
      accepting.addPointer(down2);
      tester.closeArena(6);
      tester.async.flushMicrotasks();
      tester.route(down2);
      tester.route(move2);
      expect(resolutions, <String>['rejected']);
      tester.route(up2);
      expect(resolutions, <String>['rejected']);
    });
  });
}

class TestGestureRecognizer extends GestureRecognizer {
  TestGestureRecognizer({ Object? debugOwner }) : super(debugOwner: debugOwner);

  @override
  String get debugDescription => 'debugDescription content';

  @override
  void addPointer(PointerDownEvent event) { }

  @override
  void acceptGesture(int pointer) { }

  @override
  void rejectGesture(int pointer) { }
}

/// Gesture recognizer that adds itself to the gesture arena but never
/// resolves itself.
class IndefiniteGestureRecognizer extends GestureRecognizer {
  @override
  void addAllowedPointer(PointerDownEvent event) {
    GestureBinding.instance!.gestureArena.add(event.pointer, this);
  }

  @override
  void acceptGesture(int pointer) { }

  @override
  void rejectGesture(int pointer) { }

  @override
  String get debugDescription => 'Unresolving';
}

/// Gesture recognizer that resolves with [resolution] when it handles an event
/// on the primary pointer of type [T]
class TestPrimaryPointerGestureRecognizer<T extends PointerEvent> extends PrimaryPointerGestureRecognizer {
  TestPrimaryPointerGestureRecognizer(
    this.resolution, {
    this.onAcceptGesture,
    this.onRejectGesture,
    double? preAcceptSlopTolerance,
    double? postAcceptSlopTolerance,
  }) : super(
    preAcceptSlopTolerance: preAcceptSlopTolerance,
    postAcceptSlopTolerance: postAcceptSlopTolerance,
  );

  final GestureDisposition resolution;
  final VoidCallback? onAcceptGesture;
  final VoidCallback? onRejectGesture;

  @override
  void acceptGesture(int pointer) {
    super.acceptGesture(pointer);
    if (onAcceptGesture != null) {
      onAcceptGesture!();
    }
  }

  @override
  void rejectGesture(int pointer) {
    super.rejectGesture(pointer);
    if (onRejectGesture != null) {
      onRejectGesture!();
    }
  }

  @override
  void handlePrimaryPointer(PointerEvent event) {
    if (event is T) {
      resolve(resolution);
    }
  }

  @override
  String get debugDescription => 'TestPrimaryPointer';
}
