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

// @dart = 2.8

import 'dart:async';

import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.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({Key key, 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);
  }
}
