// 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:convert';

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/common.dart';
import 'package:integration_test/integration_test.dart';
import 'package:vm_service/vm_service.dart' as vm;

vm.Timeline _kTimelines = vm.Timeline(
  traceEvents: <vm.TimelineEvent>[],
  timeOriginMicros: 100,
  timeExtentMicros: 200,
);

Future<void> main() async {
  Future<Map<String, dynamic>>? request;

  group('Test Integration binding', () {
    final IntegrationTestWidgetsFlutterBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();

    FakeVM? fakeVM;

    setUp(() {
      request = binding.callback(<String, String>{
        'command': 'request_data',
      });
      fakeVM = FakeVM(
        timeline: _kTimelines,
      );
    });

    testWidgets('Run Integration app', (WidgetTester tester) async {
      runApp(const MaterialApp(
        home: Text('Test'),
      ));
      expect(tester.binding, binding);
      binding.reportData = <String, dynamic>{'answer': 42};
      await tester.pump();
    });

    testWidgets('hitTesting works when using setSurfaceSize', (WidgetTester tester) async {
      int invocations = 0;
      await tester.pumpWidget(
        MaterialApp(
          home: Center(
            child: GestureDetector(
              onTap: () {
                invocations++;
              },
              child: const Text('Test'),
            ),
          ),
        ),
      );

      await tester.tap(find.byType(Text));
      await tester.pump();
      expect(invocations, 1);

      await tester.binding.setSurfaceSize(const Size(200, 300));
      await tester.pump();
      await tester.tap(find.byType(Text));
      await tester.pump();
      expect(invocations, 2);

      await tester.binding.setSurfaceSize(null);
      await tester.pump();
      await tester.tap(find.byType(Text));
      await tester.pump();
      expect(invocations, 3);
    });

    testWidgets('setSurfaceSize works', (WidgetTester tester) async {
      await tester.pumpWidget(const MaterialApp(home: Center(child: Text('Test'))));

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

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

      await tester.binding.setSurfaceSize(const Size(200, 300));
      await tester.pump();
      widgetCenter = tester.getRect(find.byType(Text)).center;
      expect(widgetCenter.dx, 100);
      expect(widgetCenter.dy, 150);

      await tester.binding.setSurfaceSize(null);
      await tester.pump();
      widgetCenter = tester.getRect(find.byType(Text)).center;
      expect(widgetCenter.dx, windowCenterX);
      expect(widgetCenter.dy, windowCenterY);
    });

    testWidgets('Test traceAction', (WidgetTester tester) async {
      await binding.enableTimeline(vmService: fakeVM);
      await binding.traceAction(() async {});
      expect(binding.reportData, isNotNull);
      expect(binding.reportData!.containsKey('timeline'), true);
      expect(
        json.encode(binding.reportData!['timeline']),
        json.encode(_kTimelines),
      );
    });

    group('defaultTestTimeout', () {
      final Timeout originalTimeout = binding.defaultTestTimeout;
      tearDown(() {
        binding.defaultTestTimeout = originalTimeout;
      });

      test('can be configured', () {
        const Timeout newTimeout = Timeout(Duration(seconds: 17));
        binding.defaultTestTimeout = newTimeout;
        expect(binding.defaultTestTimeout, newTimeout);
      });
    });

    // TODO(jiahaog): Remove when https://github.com/flutter/flutter/issues/66006 is fixed.
    testWidgets('root widgets are wrapped with a RepaintBoundary', (WidgetTester tester) async {
      await tester.pumpWidget(const Placeholder());

      expect(find.byType(RepaintBoundary), findsOneWidget);
    });
  });

  tearDownAll(() async {
    // This part is outside the group so that `request` has been completed as
    // part of the `tearDownAll` registered in the group during
    // `IntegrationTestWidgetsFlutterBinding` initialization.
    final Map<String, dynamic> response =
        (await request)!['response'] as Map<String, dynamic>;
    final String message = response['message'] as String;
    final Response result = Response.fromJson(message);
    assert(result.data!['answer'] == 42);
  });
}

class FakeVM extends Fake implements vm.VmService {
  FakeVM({required this.timeline});

  vm.Timeline timeline;

  @override
  Future<vm.Timeline> getVMTimeline({int? timeOriginMicros, int? timeExtentMicros}) async {
    return timeline;
  }

  int lastTimeStamp = 0;
  @override
  Future<vm.Timestamp> getVMTimelineMicros() async {
    lastTimeStamp += 100;
    return vm.Timestamp(timestamp: lastTimeStamp);
  }

  List<String> recordedStreams = <String>[];
  @override
  Future<vm.Success> setVMTimelineFlags(List<String> recordedStreams) async {
    recordedStreams = recordedStreams;
    return vm.Success();
  }

  @override
  Future<vm.Success> clearVMTimeline() async {
    return vm.Success();
  }
}
