// 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:ui' as ui show window;

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

// This is a regression test for https://github.com/flutter/flutter/issues/5840.

class Bar extends StatefulWidget {
  const Bar({ Key key }) : super(key: key);
  @override
  BarState createState() => BarState();
}

class BarState extends State<Bar> {
  final GlobalKey _fooKey = GlobalKey();

  bool _mode = false;

  void trigger() {
    setState(() {
      _mode = !_mode;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_mode) {
      return SizedBox(
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            return StatefulCreationCounter(key: _fooKey);
          },
        ),
      );
    } else {
      return LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
          return StatefulCreationCounter(key: _fooKey);
        },
      );
    }
  }
}

class StatefulCreationCounter extends StatefulWidget {
  const StatefulCreationCounter({ Key key }) : super(key: key);

  @override
  StatefulCreationCounterState createState() => StatefulCreationCounterState();
}

class StatefulCreationCounterState extends State<StatefulCreationCounter> {
  static int creationCount = 0;

  @override
  void initState() {
    super.initState();
    creationCount += 1;
  }

  @override
  Widget build(BuildContext context) => Container();
}

void main() {
  testWidgets('reparent state with layout builder', (WidgetTester tester) async {
    expect(StatefulCreationCounterState.creationCount, 0);
    await tester.pumpWidget(const Bar());
    expect(StatefulCreationCounterState.creationCount, 1);
    final BarState s = tester.state<BarState>(find.byType(Bar));
    s.trigger();
    await tester.pump();
    expect(StatefulCreationCounterState.creationCount, 1);
  });

  testWidgets('Clean then reparent with dependencies', (WidgetTester tester) async {
    int layoutBuilderBuildCount = 0;

    StateSetter keyedSetState;
    StateSetter layoutBuilderSetState;
    StateSetter childSetState;

    final GlobalKey key = GlobalKey();
    final Widget keyedWidget = StatefulBuilder(
      key: key,
      builder: (BuildContext context, StateSetter setState) {
        keyedSetState = setState;
        MediaQuery.of(context);
        return Container();
      },
    );

    Widget layoutBuilderChild = keyedWidget;
    Widget deepChild = Container();

    await tester.pumpWidget(MediaQuery(
      data: MediaQueryData.fromWindow(ui.window),
      child: Column(
        children: <Widget>[
          StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
            layoutBuilderSetState = setState;
            return LayoutBuilder(
              builder: (BuildContext context, BoxConstraints constraints) {
                layoutBuilderBuildCount += 1;
                return layoutBuilderChild; // initially keyedWidget above, but then a new Container
              },
            );
          }),
          Container(
            child: Container(
              child: Container(
                child: Container(
                  child: Container(
                    child: Container(
                      child: StatefulBuilder(
                        builder: (BuildContext context, StateSetter setState) {
                          childSetState = setState;
                          return deepChild; // initially a Container, but then the keyedWidget above
                        },
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    ));
    expect(layoutBuilderBuildCount, 1);

    keyedSetState(() { /* Change nothing but add the element to the dirty list. */ });

    childSetState(() {
      // The deep child builds in the initial build phase. It takes the child
      // from the LayoutBuilder before the LayoutBuilder has a chance to build.
      deepChild = keyedWidget;
    });

    layoutBuilderSetState(() {
      // The layout builder will build in a separate build scope. This delays
      // the removal of the keyed child until this build scope.
      layoutBuilderChild = Container();
    });

    // The essential part of this test is that this call to pump doesn't throw.
    await tester.pump();
    expect(layoutBuilderBuildCount, 2);
  });
}
