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

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

const String _actualContent = 'Actual Content';
const String _loading = 'Loading...';

void main() {
  testWidgets('deferFirstFrame/allowFirstFrame stops sending frames to engine', (WidgetTester tester) async {
    expect(RendererBinding.instance!.sendFramesToEngine, isTrue);

    final Completer<void> completer = Completer<void>();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: _DeferringWidget(
          key: UniqueKey(),
          loader: completer.future,
        ),
      ),
    );
    final _DeferringWidgetState state = tester.state<_DeferringWidgetState>(find.byType(_DeferringWidget));

    expect(find.text(_loading), findsOneWidget);
    expect(find.text(_actualContent), findsNothing);
    expect(RendererBinding.instance!.sendFramesToEngine, isFalse);

    await tester.pump();
    expect(find.text(_loading), findsOneWidget);
    expect(find.text(_actualContent), findsNothing);
    expect(RendererBinding.instance!.sendFramesToEngine, isFalse);
    expect(state.doneLoading, isFalse);

    // Complete the future to start sending frames.
    completer.complete();
    await tester.idle();
    expect(state.doneLoading, isTrue);
    expect(RendererBinding.instance!.sendFramesToEngine, isTrue);

    await tester.pump();
    expect(find.text(_loading), findsNothing);
    expect(find.text(_actualContent), findsOneWidget);
    expect(RendererBinding.instance!.sendFramesToEngine, isTrue);
  });

  testWidgets('Two widgets can defer frames', (WidgetTester tester) async {
    expect(RendererBinding.instance!.sendFramesToEngine, isTrue);

    final Completer<void> completer1 = Completer<void>();
    final Completer<void> completer2 = Completer<void>();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Row(
          children: <Widget>[
            _DeferringWidget(
              key: UniqueKey(),
              loader: completer1.future,
            ),
            _DeferringWidget(
              key: UniqueKey(),
              loader: completer2.future,
            ),
          ],
        ),
      ),
    );
    expect(find.text(_loading), findsNWidgets(2));
    expect(find.text(_actualContent), findsNothing);
    expect(RendererBinding.instance!.sendFramesToEngine, isFalse);

    completer1.complete();
    completer2.complete();
    await tester.idle();

    await tester.pump();
    expect(find.text(_loading), findsNothing);
    expect(find.text(_actualContent), findsNWidgets(2));
    expect(RendererBinding.instance!.sendFramesToEngine, isTrue);
  });
}

class _DeferringWidget extends StatefulWidget {
  const _DeferringWidget({required Key key, required this.loader}) : super(key: key);

  final Future<void> loader;

  @override
  State<_DeferringWidget> createState() => _DeferringWidgetState();
}

class _DeferringWidgetState extends State<_DeferringWidget> {
  bool doneLoading = false;

  @override
  void initState() {
    super.initState();
    RendererBinding.instance!.deferFirstFrame();
    widget.loader.then((_) {
      setState(() {
        doneLoading = true;
        RendererBinding.instance!.allowFirstFrame();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return doneLoading
        ? const Text(_actualContent)
        : const Text(_loading);
  }
}
