// 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/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('debugPrintGestureArenaDiagnostics', (WidgetTester tester) async {
    PointerEvent event;
    debugPrintGestureArenaDiagnostics = true;
    final DebugPrintCallback oldCallback = debugPrint;
    final List<String> log = <String>[];
    debugPrint = (String? s, { int? wrapWidth }) { log.add(s ?? ''); };

    final TapGestureRecognizer tap = TapGestureRecognizer()
      ..onTapDown = (TapDownDetails details) { }
      ..onTapUp = (TapUpDetails details) { }
      ..onTap = () { }
      ..onTapCancel = () { };
    expect(log, isEmpty);

    event = const PointerDownEvent(pointer: 1, position: Offset(10.0, 10.0));
    tap.addPointer(event as PointerDownEvent);
    expect(log, hasLength(2));
    expect(log[0], equalsIgnoringHashCodes('Gesture arena 1    ❙ ★ Opening new gesture arena.'));
    expect(log[1], equalsIgnoringHashCodes('Gesture arena 1    ❙ Adding: TapGestureRecognizer#00000(state: ready, button: 1)'));
    log.clear();

    GestureBinding.instance!.gestureArena.close(1);
    expect(log, hasLength(1));
    expect(log[0], equalsIgnoringHashCodes('Gesture arena 1    ❙ Closing with 1 member.'));
    log.clear();

    GestureBinding.instance!.pointerRouter.route(event);
    expect(log, isEmpty);

    event = const PointerUpEvent(pointer: 1, position: Offset(12.0, 8.0));
    GestureBinding.instance!.pointerRouter.route(event);
    expect(log, isEmpty);

    GestureBinding.instance!.gestureArena.sweep(1);
    expect(log, hasLength(2));
    expect(log[0], equalsIgnoringHashCodes('Gesture arena 1    ❙ Sweeping with 1 member.'));
    expect(log[1], equalsIgnoringHashCodes('Gesture arena 1    ❙ Winner: TapGestureRecognizer#00000(state: ready, finalPosition: Offset(12.0, 8.0), button: 1)'));
    log.clear();

    tap.dispose();
    expect(log, isEmpty);

    debugPrintGestureArenaDiagnostics = false;
    debugPrint = oldCallback;
  });

  testWidgets('debugPrintRecognizerCallbacksTrace', (WidgetTester tester) async {
    PointerEvent event;
    debugPrintRecognizerCallbacksTrace = true;
    final DebugPrintCallback oldCallback = debugPrint;
    final List<String> log = <String>[];
    debugPrint = (String? s, { int? wrapWidth }) { log.add(s ?? ''); };

    final TapGestureRecognizer tap = TapGestureRecognizer()
      ..onTapDown = (TapDownDetails details) { }
      ..onTapUp = (TapUpDetails details) { }
      ..onTap = () { }
      ..onTapCancel = () { };
    expect(log, isEmpty);

    event = const PointerDownEvent(pointer: 1, position: Offset(10.0, 10.0));
    tap.addPointer(event as PointerDownEvent);
    expect(log, isEmpty);

    GestureBinding.instance!.gestureArena.close(1);
    expect(log, isEmpty);

    GestureBinding.instance!.pointerRouter.route(event);
    expect(log, isEmpty);

    event = const PointerUpEvent(pointer: 1, position: Offset(12.0, 8.0));
    GestureBinding.instance!.pointerRouter.route(event);
    expect(log, isEmpty);

    GestureBinding.instance!.gestureArena.sweep(1);
    expect(log, hasLength(3));
    expect(log[0], equalsIgnoringHashCodes('TapGestureRecognizer#00000(state: ready, finalPosition: Offset(12.0, 8.0), button: 1) calling onTapDown callback.'));
    expect(log[1], equalsIgnoringHashCodes('TapGestureRecognizer#00000(state: ready, won arena, finalPosition: Offset(12.0, 8.0), button: 1, sent tap down) calling onTapUp callback.'));
    expect(log[2], equalsIgnoringHashCodes('TapGestureRecognizer#00000(state: ready, won arena, finalPosition: Offset(12.0, 8.0), button: 1, sent tap down) calling onTap callback.'));
    log.clear();

    tap.dispose();
    expect(log, isEmpty);

    debugPrintRecognizerCallbacksTrace = false;
    debugPrint = oldCallback;
  });

  testWidgets('debugPrintGestureArenaDiagnostics and debugPrintRecognizerCallbacksTrace', (WidgetTester tester) async {
    PointerEvent event;
    debugPrintGestureArenaDiagnostics = true;
    debugPrintRecognizerCallbacksTrace = true;
    final DebugPrintCallback oldCallback = debugPrint;
    final List<String> log = <String>[];
    debugPrint = (String? s, { int? wrapWidth }) { log.add(s ?? ''); };

    final TapGestureRecognizer tap = TapGestureRecognizer()
      ..onTapDown = (TapDownDetails details) { }
      ..onTapUp = (TapUpDetails details) { }
      ..onTap = () { }
      ..onTapCancel = () { };
    expect(log, isEmpty);

    event = const PointerDownEvent(pointer: 1, position: Offset(10.0, 10.0));
    tap.addPointer(event as PointerDownEvent);
    expect(log, hasLength(2));
    expect(log[0], equalsIgnoringHashCodes('Gesture arena 1    ❙ ★ Opening new gesture arena.'));
    expect(log[1], equalsIgnoringHashCodes('Gesture arena 1    ❙ Adding: TapGestureRecognizer#00000(state: ready, button: 1)'));
    log.clear();

    GestureBinding.instance!.gestureArena.close(1);
    expect(log, hasLength(1));
    expect(log[0], equalsIgnoringHashCodes('Gesture arena 1    ❙ Closing with 1 member.'));
    log.clear();

    GestureBinding.instance!.pointerRouter.route(event);
    expect(log, isEmpty);

    event = const PointerUpEvent(pointer: 1, position: Offset(12.0, 8.0));
    GestureBinding.instance!.pointerRouter.route(event);
    expect(log, isEmpty);

    GestureBinding.instance!.gestureArena.sweep(1);
    expect(log, hasLength(5));
    expect(log[0], equalsIgnoringHashCodes('Gesture arena 1    ❙ Sweeping with 1 member.'));
    expect(log[1], equalsIgnoringHashCodes('Gesture arena 1    ❙ Winner: TapGestureRecognizer#00000(state: ready, finalPosition: Offset(12.0, 8.0), button: 1)'));
    expect(log[2], equalsIgnoringHashCodes('                   ❙ TapGestureRecognizer#00000(state: ready, finalPosition: Offset(12.0, 8.0), button: 1) calling onTapDown callback.'));
    expect(log[3], equalsIgnoringHashCodes('                   ❙ TapGestureRecognizer#00000(state: ready, won arena, finalPosition: Offset(12.0, 8.0), button: 1, sent tap down) calling onTapUp callback.'));
    expect(log[4], equalsIgnoringHashCodes('                   ❙ TapGestureRecognizer#00000(state: ready, won arena, finalPosition: Offset(12.0, 8.0), button: 1, sent tap down) calling onTap callback.'));
    log.clear();

    tap.dispose();
    expect(log, isEmpty);

    debugPrintGestureArenaDiagnostics = false;
    debugPrintRecognizerCallbacksTrace = false;
    debugPrint = oldCallback;
  });

  test('TapGestureRecognizer _sentTapDown toString', () {
    final TapGestureRecognizer tap = TapGestureRecognizer()
      ..onTap = () {}; // Add a callback so that event can be added
    expect(tap.toString(), equalsIgnoringHashCodes('TapGestureRecognizer#00000(state: ready)'));
    const PointerDownEvent event = PointerDownEvent(pointer: 1, position: Offset(10.0, 10.0));
    tap.addPointer(event);
    tap.didExceedDeadline();
    expect(tap.toString(), equalsIgnoringHashCodes('TapGestureRecognizer#00000(state: possible, button: 1, sent tap down)'));
    GestureBinding.instance!.gestureArena.close(1);
    tap.dispose();
  });
}
