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

import '../widgets/clipboard_utils.dart';
import '../widgets/semantics_tester.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  final MockClipboard mockClipboard = MockClipboard();

  setUp(() async {
    // Fill the clipboard so that the Paste option is available in the text
    // selection menu.
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
    await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
  });

  tearDown(() {
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
  });

  testWidgets('Changing query moves cursor to the end of query', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(delegate: delegate));
    await tester.tap(find.byTooltip('Search'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 300));

    delegate.query = 'Foo';

    final TextField textField = tester.widget<TextField>(find.byType(TextField));

    expect(
      textField.controller!.selection,
      TextSelection(
        baseOffset: delegate.query.length,
        extentOffset: delegate.query.length,
      ),
    );
  });

  testWidgets('Can open and close search', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();
    final List<String> selectedResults = <String>[];

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      results: selectedResults,
    ));

    // We are on the homepage
    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('HomeTitle'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);

    // Open search
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('HomeTitle'), findsNothing);
    expect(find.text('Suggestions'), findsOneWidget);
    expect(selectedResults, hasLength(0));

    final TextField textField = tester.widget(find.byType(TextField));
    expect(textField.focusNode!.hasFocus, isTrue);

    // Close search
    await tester.tap(find.byTooltip('Back'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('HomeTitle'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);
    expect(selectedResults, <String>['Result']);
  });

  testWidgets('Can close search with system back button to return null', (WidgetTester tester) async {
    // regression test for https://github.com/flutter/flutter/issues/18145

    final _TestSearchDelegate delegate = _TestSearchDelegate();
    final List<String?> selectedResults = <String?>[];

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      results: selectedResults,
    ));

    // We are on the homepage
    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('HomeTitle'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);

    // Open search
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('HomeTitle'), findsNothing);
    expect(find.text('Suggestions'), findsOneWidget);
    expect(find.text('Bottom'), findsOneWidget);

    // Simulate system back button
    final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
    await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
    await tester.pumpAndSettle();

    expect(selectedResults, <String?>[null]);

    // We are on the homepage again
    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('HomeTitle'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);

    // Open search again
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('HomeTitle'), findsNothing);
    expect(find.text('Suggestions'), findsOneWidget);
  });

  testWidgets('Hint text color overridden', (WidgetTester tester) async {
    const String searchHintText = 'Enter search terms';
    final _TestSearchDelegate delegate = _TestSearchDelegate(searchHint: searchHintText);

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    final Text hintText = tester.widget(find.text(searchHintText));
    expect(hintText.style!.color, _TestSearchDelegate.hintTextColor);
  });

  testWidgets('Requests suggestions', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(delegate.query, '');
    expect(delegate.queriesForSuggestions.last, '');
    expect(delegate.queriesForResults, hasLength(0));

    // Type W o w into search field
    delegate.queriesForSuggestions.clear();
    await tester.enterText(find.byType(TextField), 'W');
    await tester.pumpAndSettle();
    expect(delegate.query, 'W');
    await tester.enterText(find.byType(TextField), 'Wo');
    await tester.pumpAndSettle();
    expect(delegate.query, 'Wo');
    await tester.enterText(find.byType(TextField), 'Wow');
    await tester.pumpAndSettle();
    expect(delegate.query, 'Wow');

    expect(delegate.queriesForSuggestions, <String>['W', 'Wo', 'Wow']);
    expect(delegate.queriesForResults, hasLength(0));
  });

  testWidgets('Shows Results and closes search', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();
    final List<String> selectedResults = <String>[];

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      results: selectedResults,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();
    await tester.enterText(find.byType(TextField), 'Wow');
    await tester.pumpAndSettle();
    await tester.tap(find.text('Suggestions'));
    await tester.pumpAndSettle();

    // We are on the results page for Wow
    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('HomeTitle'), findsNothing);
    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Results'), findsOneWidget);

    final TextField textField = tester.widget(find.byType(TextField));
    expect(textField.focusNode!.hasFocus, isFalse);
    expect(delegate.queriesForResults, <String>['Wow']);

    // Close search
    await tester.tap(find.byTooltip('Back'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('HomeTitle'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Results'), findsNothing);
    expect(selectedResults, <String>['Result']);
  });

  testWidgets('Can switch between results and suggestions', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    // Showing suggestions
    expect(find.text('Suggestions'), findsOneWidget);
    expect(find.text('Results'), findsNothing);

    // Typing query Wow
    delegate.queriesForSuggestions.clear();
    await tester.enterText(find.byType(TextField), 'Wow');
    await tester.pumpAndSettle();

    expect(delegate.query, 'Wow');
    expect(delegate.queriesForSuggestions, <String>['Wow']);
    expect(delegate.queriesForResults, hasLength(0));

    await tester.tap(find.text('Suggestions'));
    await tester.pumpAndSettle();

    // Showing Results
    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Results'), findsOneWidget);

    expect(delegate.query, 'Wow');
    expect(delegate.queriesForSuggestions, <String>['Wow']);
    expect(delegate.queriesForResults, <String>['Wow']);

    TextField textField = tester.widget(find.byType(TextField));
    expect(textField.focusNode!.hasFocus, isFalse);

    // Tapping search field to go back to suggestions
    await tester.tap(find.byType(TextField));
    await tester.pumpAndSettle();

    textField = tester.widget(find.byType(TextField));
    expect(textField.focusNode!.hasFocus, isTrue);

    expect(find.text('Suggestions'), findsOneWidget);
    expect(find.text('Results'), findsNothing);
    expect(delegate.queriesForSuggestions, <String>['Wow', 'Wow']);
    expect(delegate.queriesForResults, <String>['Wow']);

    await tester.enterText(find.byType(TextField), 'Foo');
    await tester.pumpAndSettle();

    expect(delegate.query, 'Foo');
    expect(delegate.queriesForSuggestions, <String>['Wow', 'Wow', 'Foo']);
    expect(delegate.queriesForResults, <String>['Wow']);

    // Go to results again
    await tester.tap(find.text('Suggestions'));
    await tester.pumpAndSettle();

    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Results'), findsOneWidget);

    expect(delegate.query, 'Foo');
    expect(delegate.queriesForSuggestions, <String>['Wow', 'Wow', 'Foo']);
    expect(delegate.queriesForResults, <String>['Wow', 'Foo']);

    textField = tester.widget(find.byType(TextField));
    expect(textField.focusNode!.hasFocus, isFalse);
  });

  testWidgets('Fresh search always starts with empty query', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(delegate.query, '');

    delegate.query = 'Foo';
    await tester.tap(find.byTooltip('Back'));
    await tester.pumpAndSettle();
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(delegate.query, '');
  });

  testWidgets('Initial queries are honored', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    expect(delegate.query, '');

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      passInInitialQuery: true,
      initialQuery: 'Foo',
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(delegate.query, 'Foo');
  });

  testWidgets('Initial query null re-used previous query', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    delegate.query = 'Foo';

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      passInInitialQuery: true,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(delegate.query, 'Foo');
  });

  testWidgets('Changing query shows up in search field', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      passInInitialQuery: true,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    delegate.query = 'Foo';

    expect(find.text('Foo'), findsOneWidget);
    expect(find.text('Bar'), findsNothing);

    delegate.query = 'Bar';

    expect(find.text('Foo'), findsNothing);
    expect(find.text('Bar'), findsOneWidget);
  });

  testWidgets('transitionAnimation runs while search fades in/out', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      passInInitialQuery: true,
    ));

    // runs while search fades in
    expect(delegate.transitionAnimation.status, AnimationStatus.dismissed);
    await tester.tap(find.byTooltip('Search'));
    expect(delegate.transitionAnimation.status, AnimationStatus.forward);
    await tester.pumpAndSettle();
    expect(delegate.transitionAnimation.status, AnimationStatus.completed);

    // does not run while switching to results
    await tester.tap(find.text('Suggestions'));
    expect(delegate.transitionAnimation.status, AnimationStatus.completed);
    await tester.pumpAndSettle();
    expect(delegate.transitionAnimation.status, AnimationStatus.completed);

    // runs while search fades out
    await tester.tap(find.byTooltip('Back'));
    expect(delegate.transitionAnimation.status, AnimationStatus.reverse);
    await tester.pumpAndSettle();
    expect(delegate.transitionAnimation.status, AnimationStatus.dismissed);
  });

  testWidgets('Closing nested search returns to search', (WidgetTester tester) async {
    final List<String?> nestedSearchResults = <String?>[];
    final _TestSearchDelegate nestedSearchDelegate = _TestSearchDelegate(
      suggestions: 'Nested Suggestions',
      result: 'Nested Result',
    );

    final List<String> selectedResults = <String>[];
    final _TestSearchDelegate delegate = _TestSearchDelegate(
      actions: <Widget>[
        Builder(
          builder: (BuildContext context) {
            return IconButton(
              tooltip: 'Nested Search',
              icon: const Icon(Icons.search),
              onPressed: () async {
                final String? result = await showSearch(
                  context: context,
                  delegate: nestedSearchDelegate,
                );
                nestedSearchResults.add(result);
              },
            );
          },
        ),
      ],
    );

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      results: selectedResults,
    ));
    expect(find.text('HomeBody'), findsOneWidget);
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('Suggestions'), findsOneWidget);
    expect(find.text('Nested Suggestions'), findsNothing);

    await tester.tap(find.byTooltip('Nested Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Nested Suggestions'), findsOneWidget);

    await tester.tap(find.byTooltip('Back'));
    await tester.pumpAndSettle();
    expect(nestedSearchResults, <String>['Nested Result']);

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('Suggestions'), findsOneWidget);
    expect(find.text('Nested Suggestions'), findsNothing);

    await tester.tap(find.byTooltip('Back'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Nested Suggestions'), findsNothing);
    expect(selectedResults, <String>['Result']);
  });

  testWidgets('Closing search with nested search shown goes back to underlying route', (WidgetTester tester) async {
    late _TestSearchDelegate delegate;
    final List<String?> nestedSearchResults = <String?>[];
    final _TestSearchDelegate nestedSearchDelegate = _TestSearchDelegate(
      suggestions: 'Nested Suggestions',
      result: 'Nested Result',
      actions: <Widget>[
        Builder(
          builder: (BuildContext context) {
            return IconButton(
              tooltip: 'Close Search',
              icon: const Icon(Icons.close),
              onPressed: () async {
                delegate.close(context, 'Result Foo');
              },
            );
          },
        ),
      ],
    );

    final List<String> selectedResults = <String>[];
    delegate = _TestSearchDelegate(
      actions: <Widget>[
        Builder(
          builder: (BuildContext context) {
            return IconButton(
              tooltip: 'Nested Search',
              icon: const Icon(Icons.search),
              onPressed: () async {
                final String? result = await showSearch(
                  context: context,
                  delegate: nestedSearchDelegate,
                );
                nestedSearchResults.add(result);
              },
            );
          },
        ),
      ],
    );

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      results: selectedResults,
    ));

    expect(find.text('HomeBody'), findsOneWidget);
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('Suggestions'), findsOneWidget);
    expect(find.text('Nested Suggestions'), findsNothing);

    await tester.tap(find.byTooltip('Nested Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Nested Suggestions'), findsOneWidget);

    await tester.tap(find.byTooltip('Close Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);
    expect(find.text('Nested Suggestions'), findsNothing);
    expect(nestedSearchResults, <String?>[null]);
    expect(selectedResults, <String>['Result Foo']);
  });

  testWidgets('Custom searchFieldLabel value', (WidgetTester tester) async {
    const String searchHint = 'custom search hint';
    final String defaultSearchHint = const DefaultMaterialLocalizations().searchFieldLabel;

    final _TestSearchDelegate delegate = _TestSearchDelegate(searchHint: searchHint);

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text(searchHint), findsOneWidget);
    expect(find.text(defaultSearchHint), findsNothing);
  });

  testWidgets('Default searchFieldLabel is used when it is set to null', (WidgetTester tester) async {
    final String searchHint = const DefaultMaterialLocalizations().searchFieldLabel;

    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text(searchHint), findsOneWidget);
  });

  testWidgets('Custom searchFieldStyle value', (WidgetTester tester) async {
    const String searchHintText = 'Enter search terms';
    const TextStyle searchFieldStyle = TextStyle(color: Colors.red, fontSize: 3);

    final _TestSearchDelegate delegate = _TestSearchDelegate(searchHint: searchHintText, searchFieldStyle: searchFieldStyle);

    await tester.pumpWidget(TestHomePage(delegate: delegate));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    final Text hintText = tester.widget(find.text(searchHintText));
    final TextField textField = tester.widget<TextField>(find.byType(TextField));

    expect(hintText.style?.color, delegate.searchFieldStyle?.color);
    expect(hintText.style?.fontSize, delegate.searchFieldStyle?.fontSize);
    expect(textField.style?.color, delegate.searchFieldStyle?.color);
    expect(textField.style?.fontSize, delegate.searchFieldStyle?.fontSize);

  });

  testWidgets('keyboard show search button by default', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate();

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    await tester.showKeyboard(find.byType(TextField));

    expect(tester.testTextInput.setClientArgs!['inputAction'], TextInputAction.search.toString());
  });

  testWidgets('Custom textInputAction results in keyboard with corresponding button', (WidgetTester tester) async {
    final _TestSearchDelegate delegate = _TestSearchDelegate(textInputAction: TextInputAction.done);

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
    ));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();
    await tester.showKeyboard(find.byType(TextField));
    expect(tester.testTextInput.setClientArgs!['inputAction'], TextInputAction.done.toString());
  });

  group('contributes semantics', () {
    TestSemantics buildExpected({ required String routeName }) {
      return TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics(
            id: 1,
            textDirection: TextDirection.ltr,
            children: <TestSemantics>[
              TestSemantics(
                id: 2,
                children: <TestSemantics>[
                  TestSemantics(
                    id: 7,
                    flags: <SemanticsFlag>[
                      SemanticsFlag.scopesRoute,
                      SemanticsFlag.namesRoute,
                    ],
                    label: routeName,
                    textDirection: TextDirection.ltr,
                    children: <TestSemantics>[
                      TestSemantics(
                        id: 9,
                        children: <TestSemantics>[
                          TestSemantics(
                            id: 10,
                            flags: <SemanticsFlag>[
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                              SemanticsFlag.isEnabled,
                              SemanticsFlag.isFocusable,
                            ],
                            actions: <SemanticsAction>[SemanticsAction.tap],
                            tooltip: 'Back',
                            textDirection: TextDirection.ltr,
                          ),
                          TestSemantics(
                            id: 11,
                            flags: <SemanticsFlag>[
                              SemanticsFlag.isTextField,
                              SemanticsFlag.isFocused,
                              SemanticsFlag.isHeader,
                              if (debugDefaultTargetPlatformOverride != TargetPlatform.iOS &&
                                debugDefaultTargetPlatformOverride != TargetPlatform.macOS) SemanticsFlag.namesRoute,
                            ],
                            actions: <SemanticsAction>[
                              if (debugDefaultTargetPlatformOverride == TargetPlatform.macOS ||
                                debugDefaultTargetPlatformOverride == TargetPlatform.windows)
                                SemanticsAction.didGainAccessibilityFocus,
                              SemanticsAction.tap,
                              SemanticsAction.setSelection,
                              SemanticsAction.setText,
                              SemanticsAction.paste,
                            ],
                            label: 'Search',
                            textDirection: TextDirection.ltr,
                            textSelection: const TextSelection(baseOffset: 0, extentOffset: 0),
                          ),
                          TestSemantics(
                            id: 14,
                            label: 'Bottom',
                            textDirection: TextDirection.ltr,
                          ),
                        ],
                      ),
                      TestSemantics(
                        id: 8,
                        flags: <SemanticsFlag>[
                          SemanticsFlag.hasEnabledState,
                          SemanticsFlag.isButton,
                          SemanticsFlag.isEnabled,
                          SemanticsFlag.isFocusable,
                        ],
                        actions: <SemanticsAction>[SemanticsAction.tap],
                        label: 'Suggestions',
                        textDirection: TextDirection.ltr,
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
        ],
      );
    }

    testWidgets('includes routeName on Android', (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      final _TestSearchDelegate delegate = _TestSearchDelegate();
      await tester.pumpWidget(TestHomePage(
        delegate: delegate,
      ));

      await tester.tap(find.byTooltip('Search'));
      await tester.pumpAndSettle();

      expect(semantics, hasSemantics(
        buildExpected(routeName: 'Search'),
        ignoreId: true,
        ignoreRect: true,
        ignoreTransform: true,
      ));

      semantics.dispose();
    });

    testWidgets('does not include routeName', (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      final _TestSearchDelegate delegate = _TestSearchDelegate();
      await tester.pumpWidget(TestHomePage(
        delegate: delegate,
      ));

      await tester.tap(find.byTooltip('Search'));
      await tester.pumpAndSettle();

      expect(semantics, hasSemantics(
        buildExpected(routeName: ''),
        ignoreId: true,
        ignoreRect: true,
        ignoreTransform: true,
      ));

      semantics.dispose();
    }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));
  });

  testWidgets('Custom searchFieldDecorationTheme value', (WidgetTester tester) async {
    const InputDecorationTheme searchFieldDecorationTheme = InputDecorationTheme(
      hintStyle: TextStyle(color: _TestSearchDelegate.hintTextColor),
    );
    final _TestSearchDelegate delegate = _TestSearchDelegate(
      searchFieldDecorationTheme: searchFieldDecorationTheme,
    );

    await tester.pumpWidget(TestHomePage(delegate: delegate));
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    final ThemeData textFieldTheme = Theme.of(tester.element(find.byType(TextField)));
    expect(textFieldTheme.inputDecorationTheme, searchFieldDecorationTheme);
  });

  // Regression test for: https://github.com/flutter/flutter/issues/66781
  testWidgets('text in search bar contrasts background (light mode)', (WidgetTester tester) async {
    final ThemeData themeData = ThemeData.light();
    final _TestSearchDelegate delegate = _TestSearchDelegate(
      defaultAppBarTheme: true,
    );
    const String query = 'search query';
    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      passInInitialQuery: true,
      initialQuery: query,
      themeData: themeData,
    ));

    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    final Material appBarBackground = tester.widget<Material>(find.descendant(
      of: find.byType(AppBar),
      matching: find.byType(Material),
    ));
    expect(appBarBackground.color, Colors.white);

    final TextField textField = tester.widget<TextField>(find.byType(TextField));
    expect(textField.style!.color, themeData.textTheme.bodyLarge!.color);
    expect(textField.style!.color, isNot(equals(Colors.white)));
  });

  // Regression test for: https://github.com/flutter/flutter/issues/66781
  testWidgets('text in search bar contrasts background (dark mode)', (WidgetTester tester) async {
    final ThemeData themeData = ThemeData.dark();
    final _TestSearchDelegate delegate = _TestSearchDelegate(
      defaultAppBarTheme: true,
    );
    const String query = 'search query';
    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      passInInitialQuery: true,
      initialQuery: query,
      themeData: themeData,
    ));

    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    final Material appBarBackground = tester.widget<Material>(find.descendant(
      of: find.byType(AppBar),
      matching: find.byType(Material),
    ));
    expect(appBarBackground.color, themeData.primaryColor);

    final TextField textField = tester.widget<TextField>(find.byType(TextField));
    expect(textField.style!.color, themeData.textTheme.bodyLarge!.color);
    expect(textField.style!.color, isNot(equals(themeData.primaryColor)));
  });

  // Regression test for: https://github.com/flutter/flutter/issues/78144
  testWidgets('`Leading` and `Actions` nullable test', (WidgetTester tester) async {
    // The search delegate page is displayed with no issues
    // even with a null return values for [buildLeading] and [buildActions].
    final _TestEmptySearchDelegate delegate = _TestEmptySearchDelegate();
    final List<String> selectedResults = <String>[];

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      results: selectedResults,
    ));

    // We are on the homepage.
    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('HomeTitle'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);

    // Open the search page.
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsNothing);
    expect(find.text('HomeTitle'), findsNothing);
    expect(find.text('Suggestions'), findsOneWidget);
    expect(selectedResults, hasLength(0));

    final TextField textField = tester.widget(find.byType(TextField));
    expect(textField.focusNode!.hasFocus, isTrue);

    // Close the search page.
    await tester.tap(find.byTooltip('Close'));
    await tester.pumpAndSettle();

    expect(find.text('HomeBody'), findsOneWidget);
    expect(find.text('HomeTitle'), findsOneWidget);
    expect(find.text('Suggestions'), findsNothing);
    expect(selectedResults, <String>['Result']);
  });

  testWidgets('showSearch with useRootNavigator', (WidgetTester tester) async {
    final _MyNavigatorObserver rootObserver = _MyNavigatorObserver();
    final _MyNavigatorObserver localObserver = _MyNavigatorObserver();

    final _TestEmptySearchDelegate delegate = _TestEmptySearchDelegate();

    await tester.pumpWidget(MaterialApp(
      navigatorObservers: <NavigatorObserver>[rootObserver],
      home: Navigator(
        observers: <NavigatorObserver>[localObserver],
        onGenerateRoute: (RouteSettings settings) {
          if (settings.name == 'nested') {
            return MaterialPageRoute<dynamic>(
              builder: (BuildContext context) => Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  TextButton(
                      onPressed: () async {
                        await showSearch(context: context, delegate: delegate, useRootNavigator: true);
                      },
                      child: const Text('showSearchRootNavigator')),
                  TextButton(
                      onPressed: () async {
                        await showSearch(context: context, delegate: delegate);
                      },
                      child: const Text('showSearchLocalNavigator')),
                ],
              ),
              settings: settings,
            );
          }
          throw UnimplementedError();
        },
        initialRoute: 'nested',
      ),
    ));

    expect(rootObserver.pushCount, 0);
    expect(localObserver.pushCount, 0);

    // showSearch normal and back
    await tester.tap(find.text('showSearchLocalNavigator'));
    await tester.pumpAndSettle();
    await tester.tap(find.byTooltip('Close'));
    await tester.pumpAndSettle();
    expect(rootObserver.pushCount, 0);
    expect(localObserver.pushCount, 1);

    // showSearch with rootNavigator
    await tester.tap(find.text('showSearchRootNavigator'));
    await tester.pumpAndSettle();
    await tester.tap(find.byTooltip('Close'));
    await tester.pumpAndSettle();
    expect(rootObserver.pushCount, 1);
    expect(localObserver.pushCount, 1);
  });

  testWidgets('Query text field shows toolbar initially', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/95588

    final _TestSearchDelegate delegate = _TestSearchDelegate();
    final List<String> selectedResults = <String>[];

    await tester.pumpWidget(TestHomePage(
      delegate: delegate,
      results: selectedResults,
    ));

    // Open search.
    await tester.tap(find.byTooltip('Search'));
    await tester.pumpAndSettle();

    final Finder textFieldFinder = find.byType(TextField);
    final TextField textField = tester.widget<TextField>(textFieldFinder);
    expect(textField.controller!.text.length, 0);

    mockClipboard.handleMethodCall(const MethodCall(
      'Clipboard.setData',
      <String, dynamic>{
        'text': 'pasteablestring',
      },
    ));

    // Long press shows toolbar.
    await tester.longPress(textFieldFinder);
    await tester.pump();
    expect(find.text('Paste'), findsOneWidget);

    await tester.tap(find.text('Paste'));
    await tester.pump();
    expect(textField.controller!.text.length, 15);
  }, skip: kIsWeb); // [intended] We do not use Flutter-rendered context menu on the Web.
}

class TestHomePage extends StatelessWidget {
  const TestHomePage({
    super.key,
    this.results,
    required this.delegate,
    this.passInInitialQuery = false,
    this.initialQuery,
    this.themeData,
  });

  final List<String?>? results;
  final SearchDelegate<String> delegate;
  final bool passInInitialQuery;
  final ThemeData? themeData;
  final String? initialQuery;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: themeData,
      home: Builder(builder: (BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('HomeTitle'),
            actions: <Widget>[
              IconButton(
                tooltip: 'Search',
                icon: const Icon(Icons.search),
                onPressed: () async {
                  String? selectedResult;
                  if (passInInitialQuery) {
                    selectedResult = await showSearch<String>(
                      context: context,
                      delegate: delegate,
                      query: initialQuery,
                    );
                  } else {
                    selectedResult = await showSearch<String>(
                      context: context,
                      delegate: delegate,
                    );
                  }
                  results?.add(selectedResult);
                },
              ),
            ],
          ),
          body: const Text('HomeBody'),
        );
      }),
    );
  }
}

class _TestSearchDelegate extends SearchDelegate<String> {
  _TestSearchDelegate({
    this.suggestions = 'Suggestions',
    this.result = 'Result',
    this.actions = const <Widget>[],
    this.defaultAppBarTheme = false,
    super.searchFieldDecorationTheme,
    super.searchFieldStyle,
    String? searchHint,
    super.textInputAction,
  }) : super(
          searchFieldLabel: searchHint,
        );

  final bool defaultAppBarTheme;
  final String suggestions;
  final String result;
  final List<Widget> actions;
  static const Color hintTextColor = Colors.green;

  @override
  ThemeData appBarTheme(BuildContext context) {
    if (defaultAppBarTheme) {
      return super.appBarTheme(context);
    }
    final ThemeData theme = Theme.of(context);
    return theme.copyWith(
      inputDecorationTheme: searchFieldDecorationTheme ??
          InputDecorationTheme(
            hintStyle: searchFieldStyle ??
                const TextStyle(
                  color: hintTextColor,
                ),
          ),
    );
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      tooltip: 'Back',
      icon: const Icon(Icons.arrow_back),
      onPressed: () {
        close(context, result);
      },
    );
  }

  final List<String> queriesForSuggestions = <String>[];
  final List<String> queriesForResults = <String>[];

  @override
  Widget buildSuggestions(BuildContext context) {
    queriesForSuggestions.add(query);
    return MaterialButton(
      onPressed: () {
        showResults(context);
      },
      child: Text(suggestions),
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    queriesForResults.add(query);
    return const Text('Results');
  }

  @override
  List<Widget> buildActions(BuildContext context) {
    return actions;
  }

  @override
  PreferredSizeWidget buildBottom(BuildContext context) {
    return const PreferredSize(
      preferredSize: Size.fromHeight(56.0),
      child: Text('Bottom'),
    );
  }
}

class _TestEmptySearchDelegate extends SearchDelegate<String> {
  @override
  Widget? buildLeading(BuildContext context) => null;

  @override
  List<Widget>? buildActions(BuildContext context) => null;

  @override
  Widget buildSuggestions(BuildContext context) {
    return MaterialButton(
      onPressed: () {
        showResults(context);
      },
      child: const Text('Suggestions'),
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    return const Text('Results');
  }

  @override
  PreferredSizeWidget buildBottom(BuildContext context) {
    return PreferredSize(
      preferredSize: const Size.fromHeight(56.0),
      child: IconButton(
        tooltip: 'Close',
        icon: const Icon(Icons.arrow_back),
        onPressed: () {
          close(context, 'Result');
        },
      ),
    );
  }
}

class _MyNavigatorObserver extends NavigatorObserver {
  int pushCount = 0;

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    // don't count the root route
    if (<String>['nested', '/'].contains(route.settings.name)) {
      return;
    }
    pushCount++;
  }
}
