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

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

import '../image_data.dart';
import '../rendering/rendering_tester.dart';

late List<int> selectedTabs;

class MockCupertinoTabController extends CupertinoTabController {
  MockCupertinoTabController({ required int initialIndex }): super(initialIndex: initialIndex);

  bool isDisposed = false;
  int numOfListeners = 0;

  @override
  void addListener(VoidCallback listener) {
    numOfListeners++;
    super.addListener(listener);
  }

  @override
  void removeListener(VoidCallback listener) {
    numOfListeners--;
    super.removeListener(listener);
  }

  @override
  void dispose() {
    isDisposed = true;
    super.dispose();
  }
}

void main() {
  setUp(() {
    selectedTabs = <int>[];
  });

  BottomNavigationBarItem tabGenerator(int index) {
    return BottomNavigationBarItem(
      icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
      label: 'Tab ${index + 1}',
    );
  }

  testWidgets('Tab switching', (WidgetTester tester) async {
    final List<int> tabsPainted = <int>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            return CustomPaint(
              painter: TestCallbackPainter(
                onPaint: () { tabsPainted.add(index); },
              ),
              child: Text('Page ${index + 1}'),
            );
          },
        ),
      ),
    );

    expect(tabsPainted, const <int>[0]);
    RichText tab1 = tester.widget(find.descendant(
      of: find.text('Tab 1'),
      matching: find.byType(RichText),
    ));
    expect(tab1.text.style!.color, CupertinoColors.activeBlue);
    RichText tab2 = tester.widget(find.descendant(
      of: find.text('Tab 2'),
      matching: find.byType(RichText),
    ));
    expect(tab2.text.style!.color!.value, 0xFF999999);

    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    expect(tabsPainted, const <int>[0, 1]);
    tab1 = tester.widget(find.descendant(
      of: find.text('Tab 1'),
      matching: find.byType(RichText),
    ));
    expect(tab1.text.style!.color!.value, 0xFF999999);
    tab2 = tester.widget(find.descendant(
      of: find.text('Tab 2'),
      matching: find.byType(RichText),
    ));
    expect(tab2.text.style!.color, CupertinoColors.activeBlue);

    await tester.tap(find.text('Tab 1'));
    await tester.pump();

    expect(tabsPainted, const <int>[0, 1, 0]);
    // CupertinoTabBar's onTap callbacks are passed on.
    expect(selectedTabs, const <int>[1, 0]);
  });

  testWidgets('Tabs are lazy built and moved offstage when inactive', (WidgetTester tester) async {
    final List<int> tabsBuilt = <int>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            tabsBuilt.add(index);
            return Text('Page ${index + 1}');
          },
        ),
      ),
    );

    expect(tabsBuilt, const <int>[0]);
    expect(find.text('Page 1'), findsOneWidget);
    expect(find.text('Page 2'), findsNothing);

    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    // Both tabs are built but only one is onstage.
    expect(tabsBuilt, const <int>[0, 0, 1]);
    expect(find.text('Page 1', skipOffstage: false), isOffstage);
    expect(find.text('Page 2'), findsOneWidget);

    await tester.tap(find.text('Tab 1'));
    await tester.pump();

    expect(tabsBuilt, const <int>[0, 0, 1, 0, 1]);
    expect(find.text('Page 1'), findsOneWidget);
    expect(find.text('Page 2', skipOffstage: false), isOffstage);
  });

  testWidgets('Last tab gets focus', (WidgetTester tester) async {
    // 2 nodes for 2 tabs
    final List<FocusNode> focusNodes = <FocusNode>[
      FocusNode(debugLabel: 'Node 1'),
      FocusNode(debugLabel: 'Node 2'),
    ];

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            return CupertinoTextField(
              focusNode: focusNodes[index],
              autofocus: true,
            );
          },
        ),
      ),
    );

    expect(focusNodes[0].hasFocus, isTrue);

    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    expect(focusNodes[0].hasFocus, isFalse);
    expect(focusNodes[1].hasFocus, isTrue);

    await tester.tap(find.text('Tab 1'));
    await tester.pump();

    expect(focusNodes[0].hasFocus, isTrue);
    expect(focusNodes[1].hasFocus, isFalse);
  });

  testWidgets('Do not affect focus order in the route', (WidgetTester tester) async {
    final List<FocusNode> focusNodes = <FocusNode>[
      FocusNode(debugLabel: 'Node 1'),
      FocusNode(debugLabel: 'Node 2'),
      FocusNode(debugLabel: 'Node 3'),
      FocusNode(debugLabel: 'Node 4'),
    ];

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            return Column(
              children: <Widget>[
                CupertinoTextField(
                  focusNode: focusNodes[index * 2],
                  placeholder: 'TextField 1',
                ),
                CupertinoTextField(
                  focusNode: focusNodes[index * 2 + 1],
                  placeholder: 'TextField 2',
                ),
              ],
            );
          },
        ),
      ),
    );

    expect(
      focusNodes.any((FocusNode node) => node.hasFocus),
      isFalse,
    );

    await tester.tap(find.widgetWithText(CupertinoTextField, 'TextField 2'));

    expect(
      focusNodes.indexOf(focusNodes.singleWhere((FocusNode node) => node.hasFocus)),
      1,
    );

    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    await tester.tap(find.widgetWithText(CupertinoTextField, 'TextField 1'));

    expect(
      focusNodes.indexOf(focusNodes.singleWhere((FocusNode node) => node.hasFocus)),
      2,
    );

    await tester.tap(find.text('Tab 1'));
    await tester.pump();

    // Upon going back to tab 1, the item it tab 1 that previously had the focus
    // (TextField 2) gets it back.
    expect(
      focusNodes.indexOf(focusNodes.singleWhere((FocusNode node) => node.hasFocus)),
      1,
    );
  });

  testWidgets('Programmatic tab switching by changing the index of an existing controller', (WidgetTester tester) async {
    final CupertinoTabController controller = CupertinoTabController(initialIndex: 1);
    final List<int> tabsPainted = <int>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          controller: controller,
          tabBuilder: (BuildContext context, int index) {
            return CustomPaint(
              painter: TestCallbackPainter(
                onPaint: () { tabsPainted.add(index); },
              ),
              child: Text('Page ${index + 1}'),
            );
          },
        ),
      ),
    );

    expect(tabsPainted, const <int>[1]);

    controller.index = 0;
    await tester.pump();

    expect(tabsPainted, const <int>[1, 0]);
    // onTap is not called when changing tabs programmatically.
    expect(selectedTabs, isEmpty);

    // Can still tap out of the programmatically selected tab.
    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    expect(tabsPainted, const <int>[1, 0, 1]);
    expect(selectedTabs, const <int>[1]);
  });

  testWidgets('Programmatic tab switching by passing in a new controller', (WidgetTester tester) async {
    final List<int> tabsPainted = <int>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            return CustomPaint(
              painter: TestCallbackPainter(
                onPaint: () { tabsPainted.add(index); },
              ),
              child: Text('Page ${index + 1}'),
            );
          },
        ),
      ),
    );

    expect(tabsPainted, const <int>[0]);

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          controller: CupertinoTabController(initialIndex: 1), // Programmatically change the tab now.
          tabBuilder: (BuildContext context, int index) {
            return CustomPaint(
              painter: TestCallbackPainter(
                onPaint: () { tabsPainted.add(index); },
              ),
              child: Text('Page ${index + 1}'),
            );
          },
        ),
      ),
    );

    expect(tabsPainted, const <int>[0, 1]);
    // onTap is not called when changing tabs programmatically.
    expect(selectedTabs, isEmpty);

    // Can still tap out of the programmatically selected tab.
    await tester.tap(find.text('Tab 1'));
    await tester.pump();

    expect(tabsPainted, const <int>[0, 1, 0]);
    expect(selectedTabs, const <int>[0]);
  });

  testWidgets('Tab bar respects themes', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            return const Placeholder();
          },
        ),
      ),
    );

    BoxDecoration tabDecoration = tester.widget<DecoratedBox>(find.descendant(
      of: find.byType(CupertinoTabBar),
      matching: find.byType(DecoratedBox),
    )).decoration as BoxDecoration;

    expect(tabDecoration.color, isSameColorAs(const Color(0xF0F9F9F9))); // Inherited from theme.

    await tester.tap(find.text('Tab 2'));
    await tester.pump();

    // Pump again but with dark theme.
    await tester.pumpWidget(
      CupertinoApp(
        theme: const CupertinoThemeData(
          brightness: Brightness.dark,
          primaryColor: CupertinoColors.destructiveRed,
        ),
        home: CupertinoTabScaffold(
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            return const Placeholder();
          },
        ),
      ),
    );

    tabDecoration = tester.widget<DecoratedBox>(find.descendant(
      of: find.byType(CupertinoTabBar),
      matching: find.byType(DecoratedBox),
    )).decoration as BoxDecoration;

    expect(tabDecoration.color, isSameColorAs(const Color(0xF01D1D1D)));

    final RichText tab1 = tester.widget(find.descendant(
      of: find.text('Tab 1'),
      matching: find.byType(RichText),
    ));
    // Tab 2 should still be selected after changing theme.
    expect(tab1.text.style!.color!.value, 0xFF757575);
    final RichText tab2 = tester.widget(find.descendant(
      of: find.text('Tab 2'),
      matching: find.byType(RichText),
    ));
    expect(tab2.text.style!.color, isSameColorAs(CupertinoColors.systemRed.darkColor));
  });

  testWidgets('Tab contents are padded when there are view insets', (WidgetTester tester) async {
    late BuildContext innerContext;

    await tester.pumpWidget(
      CupertinoApp(
        home: MediaQuery(
          data: const MediaQueryData(
            viewInsets: EdgeInsets.only(bottom: 200),
          ),
          child: CupertinoTabScaffold(
            tabBar: _buildTabBar(),
            tabBuilder: (BuildContext context, int index) {
              innerContext = context;
              return const Placeholder();
            },
          ),
        ),
      ),
    );

    expect(tester.getRect(find.byType(Placeholder)), const Rect.fromLTWH(0, 0, 800, 400));
    // Don't generate more media query padding from the translucent bottom
    // tab since the tab is behind the keyboard now.
    expect(MediaQuery.of(innerContext).padding.bottom, 0);
  });

  testWidgets('Tab contents are not inset when resizeToAvoidBottomInset overridden', (WidgetTester tester) async {
    late BuildContext innerContext;

    await tester.pumpWidget(
      CupertinoApp(
        home: MediaQuery(
          data: const MediaQueryData(
            viewInsets: EdgeInsets.only(bottom: 200),
          ),
          child: CupertinoTabScaffold(
            resizeToAvoidBottomInset: false,
            tabBar: _buildTabBar(),
            tabBuilder: (BuildContext context, int index) {
              innerContext = context;
              return const Placeholder();
            },
          ),
        ),
      ),
    );

    expect(tester.getRect(find.byType(Placeholder)), const Rect.fromLTWH(0, 0, 800, 600));
    // Media query padding shows up in the inner content because it wasn't masked
    // by the view inset.
    expect(MediaQuery.of(innerContext).padding.bottom, 50);
  });

  testWidgets('Tab contents bottom padding are not consumed by viewInsets when resizeToAvoidBottomInset overridden', (WidgetTester tester) async {
    final Widget child = Localizations(
      locale: const Locale('en', 'US'),
      delegates: const <LocalizationsDelegate<dynamic>>[
        DefaultWidgetsLocalizations.delegate,
        DefaultCupertinoLocalizations.delegate,
      ],
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: CupertinoTabScaffold(
          resizeToAvoidBottomInset: false,
          tabBar: _buildTabBar(),
          tabBuilder: (BuildContext context, int index) {
            return const Placeholder();
          },
        ),
      ),
    );

    await tester.pumpWidget(
      CupertinoApp(
        home: MediaQuery(
          data: const MediaQueryData(
            viewInsets: EdgeInsets.only(bottom: 20.0),
          ),
          child: child,
        ),
      ),
    );

    final Offset initialPoint = tester.getCenter(find.byType(Placeholder));

    // Consume bottom padding - as if by the keyboard opening
    await tester.pumpWidget(
      MediaQuery(
        data: const MediaQueryData(
          viewPadding: EdgeInsets.only(bottom: 20),
          viewInsets: EdgeInsets.only(bottom: 300),
        ),
        child: child,
      ),
    );

    final Offset finalPoint = tester.getCenter(find.byType(Placeholder));

    expect(initialPoint, finalPoint);
  });

  testWidgets(
    'Opaque tab bar consumes bottom padding while non opaque tab bar does not',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/43581.
      Future<EdgeInsets> getContentPaddingWithTabBarColor(Color color) async {
        late EdgeInsets contentPadding;

        await tester.pumpWidget(
          CupertinoApp(
            home: MediaQuery(
              data: const MediaQueryData(padding: EdgeInsets.only(bottom: 50)),
              child: CupertinoTabScaffold(
                tabBar: CupertinoTabBar(
                  backgroundColor: color,
                  items: List<BottomNavigationBarItem>.generate(2, tabGenerator),
                ),
                tabBuilder: (BuildContext context, int index) {
                  contentPadding = MediaQuery.of(context).padding;
                  return const Placeholder();
                },
              ),
            ),
          ),
        );
        return contentPadding;
      }

      expect(await getContentPaddingWithTabBarColor(const Color(0xAAFFFFFF)), isNot(EdgeInsets.zero));
      expect(await getContentPaddingWithTabBarColor(const Color(0xFFFFFFFF)), EdgeInsets.zero);
    },
  );

  testWidgets('Tab and page scaffolds do not double stack view insets', (WidgetTester tester) async {
    late BuildContext innerContext;

    await tester.pumpWidget(
      CupertinoApp(
        home: MediaQuery(
          data: const MediaQueryData(
            viewInsets: EdgeInsets.only(bottom: 200),
          ),
          child: CupertinoTabScaffold(
            tabBar: _buildTabBar(),
            tabBuilder: (BuildContext context, int index) {
              return CupertinoPageScaffold(
                child: Builder(
                  builder: (BuildContext context) {
                    innerContext = context;
                    return const Placeholder();
                  },
                ),
              );
            },
          ),
        ),
      ),
    );

    expect(tester.getRect(find.byType(Placeholder)), const Rect.fromLTWH(0, 0, 800, 400));
    expect(MediaQuery.of(innerContext).padding.bottom, 0);
  });

  testWidgets('Deleting tabs after selecting them should switch to the last available tab', (WidgetTester tester) async {
    final List<int> tabsBuilt = <int>[];

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(4, tabGenerator),
            onTap: (int newTab) => selectedTabs.add(newTab),
          ),
          tabBuilder: (BuildContext context, int index) {
            tabsBuilt.add(index);
            return Text('Page ${index + 1}');
          },
        ),
      ),
    );

    expect(tabsBuilt, const <int>[0]);
    // selectedTabs list is appended to on onTap callbacks. We didn't tap
    // any tabs yet.
    expect(selectedTabs, const <int>[]);
    tabsBuilt.clear();

    await tester.tap(find.text('Tab 4'));
    await tester.pump();

    // Tabs 1 and 4 are built but only one is onstage.
    expect(tabsBuilt, const <int>[0, 3]);
    expect(selectedTabs, const <int>[3]);
    expect(find.text('Page 1', skipOffstage: false), isOffstage);
    expect(find.text('Page 4'), findsOneWidget);
    tabsBuilt.clear();

    // Delete 2 tabs while Page 4 is still selected.
    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(2, tabGenerator),
            onTap: (int newTab) => selectedTabs.add(newTab),
          ),
          tabBuilder: (BuildContext context, int index) {
            tabsBuilt.add(index);
            // Change the builder too.
            return Text('Different page ${index + 1}');
          },
        ),
      ),
    );

    expect(tabsBuilt, const <int>[0, 1]);
    // We didn't tap on any additional tabs to invoke the onTap callback. We
    // just deleted a tab.
    expect(selectedTabs, const <int>[3]);
    // Tab 1 was previously built so it's rebuilt again, albeit offstage.
    expect(find.text('Different page 1', skipOffstage: false), isOffstage);
    // Since all the tabs after tab 2 are deleted, tab 2 is now the last tab and
    // the actively shown tab.
    expect(find.text('Different page 2'), findsOneWidget);
    // No more tab 4 since it's deleted.
    expect(find.text('Different page 4', skipOffstage: false), findsNothing);
    // We also changed the builder so no tabs should be built with the old
    // builder.
    expect(find.text('Page 1', skipOffstage: false), findsNothing);
    expect(find.text('Page 2', skipOffstage: false), findsNothing);
    expect(find.text('Page 4', skipOffstage: false), findsNothing);
  });

  // Regression test for https://github.com/flutter/flutter/issues/33455
  testWidgets('Adding new tabs does not crash the app', (WidgetTester tester) async {
    final List<int> tabsPainted = <int>[];
    final CupertinoTabController controller = CupertinoTabController();

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(10, tabGenerator),
          ),
          controller: controller,
          tabBuilder: (BuildContext context, int index) {
            return CustomPaint(
              painter: TestCallbackPainter(
                onPaint: () { tabsPainted.add(index); },
              ),
              child: Text('Page ${index + 1}'),
            );
          },
        ),
      ),
    );

    expect(tabsPainted, const <int> [0]);

    // Increase the num of tabs to 20.
    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(20, tabGenerator),
          ),
          controller: controller,
          tabBuilder: (BuildContext context, int index) {
            return CustomPaint(
              painter: TestCallbackPainter(
                onPaint: () { tabsPainted.add(index); },
              ),
              child: Text('Page ${index + 1}'),
            );
          },
        ),
      ),
    );

    expect(tabsPainted, const <int> [0, 0]);

    await tester.tap(find.text('Tab 19'));
    await tester.pump();

    // Tapping the tabs should still work.
    expect(tabsPainted, const <int>[0, 0, 18]);
  });

  testWidgets(
    'If a controller is initially provided then the parent stops doing so for rebuilds, '
    'a new instance of CupertinoTabController should be created and used by the widget, '
    "while preserving the previous controller's tab index",
    (WidgetTester tester) async {
      final List<int> tabsPainted = <int>[];
      final CupertinoTabController oldController = CupertinoTabController();

      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: List<BottomNavigationBarItem>.generate(10, tabGenerator),
            ),
            controller: oldController,
            tabBuilder: (BuildContext context, int index) {
              return CustomPaint(
                painter: TestCallbackPainter(
                  onPaint: () { tabsPainted.add(index); },
                ),
                child: Text('Page ${index + 1}'),
              );
            },
          ),
        ),
      );

      expect(tabsPainted, const <int> [0]);

      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: List<BottomNavigationBarItem>.generate(10, tabGenerator),
            ),
            tabBuilder:
            (BuildContext context, int index) {
              return CustomPaint(
                painter: TestCallbackPainter(
                  onPaint: () { tabsPainted.add(index); },
                ),
                child: Text('Page ${index + 1}'),
              );
            },
          ),
        ),
      );

      expect(tabsPainted, const <int> [0, 0]);

      await tester.tap(find.text('Tab 2'));
      await tester.pump();

      // Tapping the tabs should still work.
      expect(tabsPainted, const <int>[0, 0, 1]);

      oldController.index = 10;
      await tester.pump();

      // Changing [index] of the oldController should not work.
      expect(tabsPainted, const <int> [0, 0, 1]);
    },
  );

  testWidgets(
    'Do not call dispose on a controller that we do not own '
    'but do remove from its listeners when done listening to it',
    (WidgetTester tester) async {
      final MockCupertinoTabController mockController = MockCupertinoTabController(initialIndex: 0);

      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: List<BottomNavigationBarItem>.generate(2, tabGenerator),
            ),
            controller: mockController,
            tabBuilder: (BuildContext context, int index) => const Placeholder(),
          ),
        ),
      );

      expect(mockController.numOfListeners, 1);
      expect(mockController.isDisposed, isFalse);

      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: List<BottomNavigationBarItem>.generate(2, tabGenerator),
            ),
            tabBuilder: (BuildContext context, int index) => const Placeholder(),
          ),
        ),
      );

      expect(mockController.numOfListeners, 0);
      expect(mockController.isDisposed, isFalse);
    },
  );

  testWidgets('The owner can dispose the old controller', (WidgetTester tester) async {
    CupertinoTabController controller = CupertinoTabController(initialIndex: 2);

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(3, tabGenerator),
          ),
          controller: controller,
          tabBuilder: (BuildContext context, int index) => const Placeholder(),
        ),
      ),
    );
    expect(find.text('Tab 1'), findsOneWidget);
    expect(find.text('Tab 2'), findsOneWidget);
    expect(find.text('Tab 3'), findsOneWidget);

    controller.dispose();
    controller = CupertinoTabController();
    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(2, tabGenerator),
          ),
          controller: controller,
          tabBuilder: (BuildContext context, int index) => const Placeholder(),
        ),
      ),
    );

    // Should not crash here.
    expect(find.text('Tab 1'), findsOneWidget);
    expect(find.text('Tab 2'), findsOneWidget);
    expect(find.text('Tab 3'), findsNothing);
  });

  testWidgets('A controller can control more than one CupertinoTabScaffold, '
    'removal of listeners does not break the controller',
    (WidgetTester tester) async {
      final List<int> tabsPainted0 = <int>[];
      final List<int> tabsPainted1 = <int>[];
      MockCupertinoTabController controller = MockCupertinoTabController(initialIndex: 2);

      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoPageScaffold(
            child: Stack(
              children: <Widget>[
                CupertinoTabScaffold(
                  tabBar: CupertinoTabBar(
                    items: List<BottomNavigationBarItem>.generate(3, tabGenerator),
                  ),
                  controller: controller,
                  tabBuilder: (BuildContext context, int index) {
                    return CustomPaint(
                      painter: TestCallbackPainter(
                        onPaint: () => tabsPainted0.add(index),
                      ),
                    );
                  },
                ),
                CupertinoTabScaffold(
                  tabBar: CupertinoTabBar(
                    items: List<BottomNavigationBarItem>.generate(3, tabGenerator),
                  ),
                  controller: controller,
                  tabBuilder: (BuildContext context, int index) {
                    return CustomPaint(
                      painter: TestCallbackPainter(
                        onPaint: () => tabsPainted1.add(index),
                      ),
                    );
                  },
                ),
              ],
            ),
          ),
        ),
      );
      expect(tabsPainted0, const <int>[2]);
      expect(tabsPainted1, const <int>[2]);
      expect(controller.numOfListeners, 2);

      controller.index = 0;
      await tester.pump();
      expect(tabsPainted0, const <int>[2, 0]);
      expect(tabsPainted1, const <int>[2, 0]);

      controller.index = 1;
      // Removing one of the tabs works.
      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoPageScaffold(
            child: Stack(
              children: <Widget>[
                CupertinoTabScaffold(
                  tabBar: CupertinoTabBar(
                    items: List<BottomNavigationBarItem>.generate(3, tabGenerator),
                  ),
                  controller: controller,
                  tabBuilder: (BuildContext context, int index) {
                    return CustomPaint(
                      painter: TestCallbackPainter(
                        onPaint: () => tabsPainted0.add(index),
                      ),
                    );
                  },
                ),
              ],
            ),
          ),
        ),
      );

      expect(tabsPainted0, const <int>[2, 0, 1]);
      expect(tabsPainted1, const <int>[2, 0]);
      expect(controller.numOfListeners, 1);

      // Replacing controller works.
      controller = MockCupertinoTabController(initialIndex: 2);
      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoPageScaffold(
            child: Stack(
              children: <Widget>[
                CupertinoTabScaffold(
                  tabBar: CupertinoTabBar(
                    items: List<BottomNavigationBarItem>.generate(3, tabGenerator),
                  ),
                  controller: controller,
                  tabBuilder: (BuildContext context, int index) {
                    return CustomPaint(
                      painter: TestCallbackPainter(
                        onPaint: () => tabsPainted0.add(index),
                      ),
                    );
                  },
                ),
              ],
            ),
          ),
        ),
      );
      expect(tabsPainted0, const <int>[2, 0, 1, 2]);
      expect(tabsPainted1, const <int>[2, 0]);
      expect(controller.numOfListeners, 1);
    },
  );

  testWidgets('Assert when current tab index >= number of tabs', (WidgetTester tester) async {
    final CupertinoTabController controller = CupertinoTabController(initialIndex: 2);

    try {
      await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: List<BottomNavigationBarItem>.generate(2, tabGenerator),
            ),
            controller: controller,
            tabBuilder: (BuildContext context, int index) => Text('Different page ${index + 1}'),
          ),
        ),
      );
    } on AssertionError catch (e) {
      expect(e.toString(), contains('controller.index < tabBar.items.length'));
    }

    await tester.pumpWidget(
      CupertinoApp(
        home: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(3, tabGenerator),
          ),
          controller: controller,
          tabBuilder: (BuildContext context, int index) => Text('Different page ${index + 1}'),
        ),
      ),
    );

    expect(tester.takeException(), null);

    controller.index = 10;
    await tester.pump();

    final String message = tester.takeException().toString();
    expect(message, contains('current index ${controller.index}'));
    expect(message, contains('with 3 tabs'));
  });

  testWidgets("Don't replace focus nodes for existing tabs when changing tab count", (WidgetTester tester) async {
    final CupertinoTabController controller = CupertinoTabController(initialIndex: 2);

    final List<FocusScopeNode> scopes = List<FocusScopeNode>.filled(5, FocusScopeNode());
    await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: List<BottomNavigationBarItem>.generate(3, tabGenerator),
            ),
            controller: controller,
            tabBuilder: (BuildContext context, int index) {
              scopes[index] = FocusScope.of(context);
              return Container();
            },
          ),
        ),
    );

    for (int i = 0; i < 3; i++) {
      controller.index = i;
      await tester.pump();
    }
    await tester.pump();

    final List<FocusScopeNode> newScopes = <FocusScopeNode>[];
    await tester.pumpWidget(
        CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: List<BottomNavigationBarItem>.generate(5, tabGenerator),
            ),
            controller: controller,
            tabBuilder: (BuildContext context, int index) {
              newScopes.add(FocusScope.of(context));
              return Container();
            },
          ),
        ),
    );
    for (int i = 0; i < 5; i++) {
      controller.index = i;
      await tester.pump();
    }
    await tester.pump();

    expect(scopes.sublist(0, 3), equals(newScopes.sublist(0, 3)));
  });

  testWidgets('Current tab index cannot go below zero or be null', (WidgetTester tester) async {
    void expectAssertionError(VoidCallback callback, String errorMessage) {
      try {
        callback();
      } on AssertionError catch (e) {
        expect(e.toString(), contains(errorMessage));
      }
    }

    expectAssertionError(() => CupertinoTabController(initialIndex: -1), '>= 0');

    final CupertinoTabController controller = CupertinoTabController();

    expectAssertionError(() => controller.index = -1, '>= 0');
  });

  testWidgets('Does not lose state when focusing on text input', (WidgetTester tester) async {
    // Regression testing for https://github.com/flutter/flutter/issues/28457.

    await tester.pumpWidget(
      MediaQuery(
        data: const MediaQueryData(),
        child: CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: _buildTabBar(),
            tabBuilder: (BuildContext context, int index) {
              return const CupertinoTextField();
            },
          ),
        ),
      ),
    );

    final EditableTextState editableState = tester.state<EditableTextState>(find.byType(EditableText));

    await tester.enterText(find.byType(CupertinoTextField), "don't lose me");

    await tester.pumpWidget(
      MediaQuery(
        data: const MediaQueryData(
          viewInsets:  EdgeInsets.only(bottom: 100),
        ),
        child: CupertinoApp(
          home: CupertinoTabScaffold(
            tabBar: _buildTabBar(),
            tabBuilder: (BuildContext context, int index) {
              return const CupertinoTextField();
            },
          ),
        ),
      ),
    );

    // The exact same state instance is still there.
    expect(tester.state<EditableTextState>(find.byType(EditableText)), editableState);
    expect(find.text("don't lose me"), findsOneWidget);
  });

  testWidgets('textScaleFactor is set to 1.0', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Builder(builder: (BuildContext context) {
          return MediaQuery(
            data: MediaQuery.of(context).copyWith(textScaleFactor: 99),
            child: CupertinoTabScaffold(
              tabBar: CupertinoTabBar(
                items: List<BottomNavigationBarItem>.generate(
                  10,
                  (int i) => BottomNavigationBarItem(icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))), label: '$i'),
                ),
              ),
              tabBuilder: (BuildContext context, int index) => const Text('content'),
            ),
          );
        }),
      ),
    );

    final Iterable<RichText> barItems = tester.widgetList<RichText>(
      find.descendant(
        of: find.byType(CupertinoTabBar),
        matching: find.byType(RichText),
      ),
    );

    final Iterable<RichText> contents = tester.widgetList<RichText>(
      find.descendant(
        of: find.text('content'),
        matching: find.byType(RichText),
        skipOffstage: false,
      ),
    );

    expect(barItems.length, greaterThan(0));
    expect(barItems.any((RichText t) => t.textScaleFactor != 1), isFalse);

    expect(contents.length, greaterThan(0));
    expect(contents.any((RichText t) => t.textScaleFactor != 99), isFalse);
  });

  testWidgets('state restoration', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        restorationScopeId: 'app',
        home: CupertinoTabScaffold(
          restorationId: 'scaffold',
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(
              4,
              (int i) => BottomNavigationBarItem(icon: const Icon(CupertinoIcons.map), label: 'Tab $i'),
            ),
          ),
          tabBuilder: (BuildContext context, int i) => Text('Content $i'),
        ),
      ),
    );

    expect(find.text('Content 0'), findsOneWidget);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsNothing);
    expect(find.text('Content 3'), findsNothing);

    await tester.tap(find.text('Tab 2'));
    await tester.pumpAndSettle();

    expect(find.text('Content 0'), findsNothing);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsOneWidget);
    expect(find.text('Content 3'), findsNothing);

    await tester.restartAndRestore();

    expect(find.text('Content 0'), findsNothing);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsOneWidget);
    expect(find.text('Content 3'), findsNothing);

    final TestRestorationData data = await tester.getRestorationData();

    await tester.tap(find.text('Tab 1'));
    await tester.pumpAndSettle();

    expect(find.text('Content 0'), findsNothing);
    expect(find.text('Content 1'), findsOneWidget);
    expect(find.text('Content 2'), findsNothing);
    expect(find.text('Content 3'), findsNothing);

    await tester.restoreFrom(data);

    expect(find.text('Content 0'), findsNothing);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsOneWidget);
    expect(find.text('Content 3'), findsNothing);
  });

  testWidgets('switch from internal to external controller with state restoration', (WidgetTester tester) async {
    Widget buildWidget({CupertinoTabController? controller}) {
      return CupertinoApp(
        restorationScopeId: 'app',
        home: CupertinoTabScaffold(
          controller: controller,
          restorationId: 'scaffold',
          tabBar: CupertinoTabBar(
            items: List<BottomNavigationBarItem>.generate(
              4,
              (int i) => BottomNavigationBarItem(icon: const Icon(CupertinoIcons.map), label: 'Tab $i'),
            ),
          ),
          tabBuilder: (BuildContext context, int i) => Text('Content $i'),
        ),
      );
    }

    await tester.pumpWidget(buildWidget());

    expect(find.text('Content 0'), findsOneWidget);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsNothing);
    expect(find.text('Content 3'), findsNothing);

    await tester.tap(find.text('Tab 2'));
    await tester.pumpAndSettle();

    expect(find.text('Content 0'), findsNothing);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsOneWidget);
    expect(find.text('Content 3'), findsNothing);

    final CupertinoTabController controller = CupertinoTabController(initialIndex: 3);
    await tester.pumpWidget(buildWidget(controller: controller));

    expect(find.text('Content 0'), findsNothing);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsNothing);
    expect(find.text('Content 3'), findsOneWidget);

    await tester.pumpWidget(buildWidget());

    expect(find.text('Content 0'), findsOneWidget);
    expect(find.text('Content 1'), findsNothing);
    expect(find.text('Content 2'), findsNothing);
    expect(find.text('Content 3'), findsNothing);
  });
}

CupertinoTabBar _buildTabBar({ int selectedTab = 0 }) {
  return CupertinoTabBar(
    items: <BottomNavigationBarItem>[
      BottomNavigationBarItem(
        icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
        label: 'Tab 1',
      ),
      BottomNavigationBarItem(
        icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
        label: 'Tab 2',
      ),
    ],
    currentIndex: selectedTab,
    onTap: (int newTab) => selectedTabs.add(newTab),
  );
}
