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

// Only check the initial lines of the message, since the message walks the
// entire widget tree back, and any changes to the widget tree break these
// tests if we check the entire message.
void _expectStartsWith(List<String?> actual, List<String?> matcher) {
  expect(actual.sublist(0, matcher.length), equals(matcher));
}

void main() {
  final _MockLiveTestWidgetsFlutterBinding binding = _MockLiveTestWidgetsFlutterBinding();

  testWidgets('Should print message on pointer events', (WidgetTester tester) async {
    final List<String?> printedMessages = <String?>[];

    int invocations = 0;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: GestureDetector(
            onTap: () {
              invocations++;
            },
            child: const Text('Test'),
          ),
        ),
      ),
    );

    final Size windowCenter = tester.binding.window.physicalSize /
        tester.binding.window.devicePixelRatio /
        2;
    final double windowCenterX = windowCenter.width;
    final double windowCenterY = windowCenter.height;

    final Offset widgetCenter = tester.getRect(find.byType(Text)).center;
    expect(widgetCenter.dx, windowCenterX);
    expect(widgetCenter.dy, windowCenterY);

    await binding.collectDebugPrints(printedMessages, () async {
      await tester.tap(find.byType(Text));
    });
    await tester.pump();
    expect(invocations, 0);

    _expectStartsWith(printedMessages, '''
Some possible finders for the widgets at Offset(400.0, 300.0):
  find.text('Test')
'''.trim().split('\n'));
    printedMessages.clear();

    await binding.collectDebugPrints(printedMessages, () async {
      await tester.tapAt(const Offset(1, 1));
    });
    expect(printedMessages, equals('''
No widgets found at Offset(1.0, 1.0).
'''.trim().split('\n')));
  });

  testWidgets('Should print message on pointer events with setSurfaceSize', (WidgetTester tester) async {
    final List<String?> printedMessages = <String?>[];

    int invocations = 0;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child:GestureDetector(
            onTap: () {
              invocations++;
            },
            child: const Text('Test'),
          ),
        ),
      ),
    );

    final Size originalSize = tester.binding.createViewConfiguration().size;
    await tester.binding.setSurfaceSize(const Size(2000, 1800));
    try {
      await tester.pump();

      final Offset widgetCenter = tester.getRect(find.byType(Text)).center;
      expect(widgetCenter.dx, 1000);
      expect(widgetCenter.dy, 900);

      await binding.collectDebugPrints(printedMessages, () async {
        await tester.tap(find.byType(Text));
      });
      await tester.pump();
      expect(invocations, 0);

      _expectStartsWith(printedMessages, '''
Some possible finders for the widgets at Offset(1000.0, 900.0):
  find.text('Test')
'''.trim().split('\n'));
      printedMessages.clear();

      await binding.collectDebugPrints(printedMessages, () async {
        await tester.tapAt(const Offset(1, 1));
      });
      expect(printedMessages, equals('''
No widgets found at Offset(1.0, 1.0).
'''.trim().split('\n')));
    } finally {
      await tester.binding.setSurfaceSize(originalSize);
    }
  });
}

class _MockLiveTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding {
  @override
  void handlePointerEventForSource(
    PointerEvent event, {
    TestBindingEventSource source = TestBindingEventSource.device,
  }) {
    // In this test we use `WidgetTester.tap` to simulate real device touches.
    // `WidgetTester.tap` sends events in the local coordinate system, while
    // real devices touches sends event in the global coordinate system.
    // See the documentation of [handlePointerEventForSource] for details.
    if (source == TestBindingEventSource.test) {
      final PointerEvent globalEvent = event.copyWith(position: localToGlobal(event.position));
      return super.handlePointerEventForSource(globalEvent);
    }
    return super.handlePointerEventForSource(event, source: source);
  }

  List<String?>? _storeDebugPrints;

  @override
  DebugPrintCallback get debugPrintOverride {
    return _storeDebugPrints == null
        ? super.debugPrintOverride
        : ((String? message, { int? wrapWidth }) => _storeDebugPrints!.add(message));
  }

  // Execute `task` while redirecting [debugPrint] to appending to `store`.
  Future<void> collectDebugPrints(List<String?>? store, AsyncValueGetter<void> task) async {
    _storeDebugPrints = store;
    try {
      await task();
    } finally {
      _storeDebugPrints = null;
    }
  }
}
