// 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 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

class TestWidget extends StatefulWidget {
  const TestWidget({
    Key? key,
    required this.child,
    required this.persistentState,
    required this.syncedState,
  }) : super(key: key);

  final Widget child;
  final int persistentState;
  final int syncedState;

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

class TestWidgetState extends State<TestWidget> {
  late int persistentState;
  late int syncedState;
  int updates = 0;

  @override
  void initState() {
    super.initState();
    persistentState = widget.persistentState;
    syncedState = widget.syncedState;
  }

  @override
  void didUpdateWidget(TestWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    syncedState = widget.syncedState;
    // we explicitly do NOT sync the persistentState from the new instance
    // because we're using that to track whether we got recreated
    updates += 1;
  }

  @override
  Widget build(BuildContext context) => widget.child;
}

void main() {

  testWidgets('no change', (WidgetTester tester) async {
    await tester.pumpWidget(
      Container(
        color: Colors.blue,
        child: Container(
          color: Colors.blue,
          child: TestWidget(
            persistentState: 1,
            syncedState: 0,
            child: Container(),
          ),
        ),
      ),
    );

    final TestWidgetState state = tester.state(find.byType(TestWidget));

    expect(state.persistentState, equals(1));
    expect(state.updates, equals(0));

    await tester.pumpWidget(
      Container(
        color: Colors.blue,
        child: Container(
          color: Colors.blue,
          child: TestWidget(
            persistentState: 2,
            syncedState: 0,
            child: Container(),
          ),
        ),
      ),
    );

    expect(state.persistentState, equals(1));
    expect(state.updates, equals(1));

    await tester.pumpWidget(Container());
  });

  testWidgets('remove one', (WidgetTester tester) async {
    await tester.pumpWidget(
      Container(
        color: Colors.blue,
        child: Container(
          color: Colors.blue,
          child: TestWidget(
            persistentState: 10,
            syncedState: 0,
            child: Container(),
          ),
        ),
      ),
    );

    TestWidgetState state = tester.state(find.byType(TestWidget));

    expect(state.persistentState, equals(10));
    expect(state.updates, equals(0));

    await tester.pumpWidget(
      Container(
        color: Colors.green,
        child: TestWidget(
          persistentState: 11,
          syncedState: 0,
          child: Container(),
        ),
      ),
    );

    state = tester.state(find.byType(TestWidget));

    expect(state.persistentState, equals(11));
    expect(state.updates, equals(0));

    await tester.pumpWidget(Container());
  });

  testWidgets('swap instances around', (WidgetTester tester) async {
    const Widget a = TestWidget(persistentState: 0x61, syncedState: 0x41, child: Text('apple', textDirection: TextDirection.ltr));
    const Widget b = TestWidget(persistentState: 0x62, syncedState: 0x42, child: Text('banana', textDirection: TextDirection.ltr));
    await tester.pumpWidget(Column());

    final GlobalKey keyA = GlobalKey();
    final GlobalKey keyB = GlobalKey();

    await tester.pumpWidget(
      Column(
        children: <Widget>[
          Container(
            key: keyA,
            child: a,
          ),
          Container(
            key: keyB,
            child: b,
          ),
        ],
      ),
    );

    TestWidgetState first, second;

    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));

    expect(first.widget, equals(a));
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
    expect(second.widget, equals(b));
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x42));

    await tester.pumpWidget(
      Column(
        children: <Widget>[
          Container(
            key: keyA,
            child: a,
          ),
          Container(
            key: keyB,
            child: b,
          ),
        ],
      ),
    );

    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));

    // same as before
    expect(first.widget, equals(a));
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
    expect(second.widget, equals(b));
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x42));

    // now we swap the nodes over
    // since they are both "old" nodes, they shouldn't sync with each other even though they look alike

    await tester.pumpWidget(
      Column(
        children: <Widget>[
          Container(
            key: keyA,
            child: b,
          ),
          Container(
            key: keyB,
            child: a,
          ),
        ],
      ),
    );

    first = tester.state(find.byWidget(b));
    second = tester.state(find.byWidget(a));

    expect(first.widget, equals(b));
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x42));
    expect(second.widget, equals(a));
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x41));
  });
}
