// 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.

// TODO(gspencergoog): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/85160
// Fails with "flutter test --test-randomize-ordering-seed=20210721"
@Tags(<String>['no-shuffle'])
library;

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

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

  group(TestViewConfiguration, () {
    test('is initialized with top-level window if one is not provided', () {
      // The code below will throw without the default.
      TestViewConfiguration(size: const Size(1280.0, 800.0));
    });

    test('toMatrix handles zero size', () {
      // The code below will throw without the default.
      final Matrix4 matrix = TestViewConfiguration(size: Size.zero).toMatrix();
      expect(matrix.storage.every((double x) => x.isFinite), isTrue);
    });

    test('sets the DPR to match the window', () {
      final configuration = TestViewConfiguration(size: const Size(1280.0, 800.0));
      expect(configuration.devicePixelRatio, binding.window.devicePixelRatio);
    });
  });

  group(AutomatedTestWidgetsFlutterBinding, () {
    test('allows setting defaultTestTimeout to 5 minutes', () {
      binding.defaultTestTimeout = const Timeout(Duration(minutes: 5));
      expect(binding.defaultTestTimeout.duration, const Duration(minutes: 5));
    });
  });

  // The next three tests must run in order -- first using `test`, then `testWidgets`, then `test` again.

  var order = 0;

  test('Initializes httpOverrides and testTextInput', () async {
    assert(order == 0);
    expect(binding.testTextInput, isNotNull);
    expect(binding.testTextInput.isRegistered, isFalse);
    expect(HttpOverrides.current, isNotNull);
    order += 1;
  });

  testWidgets('Registers testTextInput', (WidgetTester tester) async {
    assert(order == 1);
    expect(tester.testTextInput.isRegistered, isTrue);
    order += 1;
  });

  test('Unregisters testTextInput', () async {
    assert(order == 2);
    expect(binding.testTextInput.isRegistered, isFalse);
    order += 1;
  });

  testWidgets('timeStamp should be accurate to microsecond precision', (WidgetTester tester) async {
    final WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();

    await tester.pumpWidget(const CircularProgressIndicator());

    final Duration timeStampBefore = widgetsBinding.currentSystemFrameTimeStamp;
    await tester.pump(const Duration(microseconds: 12345));
    final Duration timeStampAfter = widgetsBinding.currentSystemFrameTimeStamp;

    expect(timeStampAfter - timeStampBefore, const Duration(microseconds: 12345));
  });

  group('elapseBlocking', () {
    testWidgets('timer is not called', (WidgetTester tester) async {
      var timerCalled = false;
      Timer.run(() => timerCalled = true);

      binding.elapseBlocking(const Duration(seconds: 1));

      expect(timerCalled, false);
      await binding.idle();
    });

    testWidgets('can use to simulate slow build', (WidgetTester tester) async {
      final DateTime beforeTime = binding.clock.now();

      await tester.pumpWidget(
        Builder(
          builder: (_) {
            var timerCalled = false;
            Timer.run(() => timerCalled = true);

            binding.elapseBlocking(const Duration(seconds: 1));

            // if we use `delayed` instead of `elapseBlocking`, such as
            // binding.delayed(const Duration(seconds: 1));
            // the timer will be called here. Surely, that violates how
            // a flutter widget build works
            expect(timerCalled, false);

            return Container();
          },
        ),
      );

      expect(binding.clock.now(), beforeTime.add(const Duration(seconds: 1)));
      await binding.idle();
    });
  });

  testWidgets('Assets in the tester can be loaded without turning event loop', (
    WidgetTester tester,
  ) async {
    var responded = false;
    // The particular asset does not matter, as long as it exists.
    // ignore: unawaited_futures
    rootBundle.load('AssetManifest.bin').then((ByteData data) {
      responded = true;
    });
    expect(responded, true);
  });
}
