// 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() {
  TestWidgetsFlutterBinding.ensureInitialized();

  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({ super.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,
    super.preAcceptSlopTolerance,
    super.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';
}
