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

class TestRoute extends PageRouteBuilder<void> {
  TestRoute(Widget child) : super(
    pageBuilder: (BuildContext _, Animation<double> __, Animation<double> ___) => child,
  );
}

class IconTextBox extends StatelessWidget {
  const IconTextBox(this.text, { Key? key }) : super(key: key);
  final String text;
  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      child: Row(
        children: <Widget>[const Icon(IconData(0x41, fontFamily: 'Roboto')), Text(text)],
      ),
    );
  }
}

void main() {
  testWidgets('InheritedTheme.captureAll()', (WidgetTester tester) async {
    const double fontSize = 32;
    const double iconSize = 48;
    const Color textColor = Color(0xFF00FF00);
    const Color iconColor = Color(0xFF0000FF);
    bool useCaptureAll = false;
    late BuildContext navigatorContext;

    Widget buildFrame() {
      return WidgetsApp(
        color: const Color(0xFFFFFFFF),
        onGenerateRoute: (RouteSettings settings) {
          return TestRoute(
            // The outer DefaultTextStyle and IconTheme widgets must have
            // no effect on the test because InheritedTheme.captureAll()
            // is required to only save the closest InheritedTheme ancestors.
            DefaultTextStyle(
              style: const TextStyle(fontSize: iconSize, color: iconColor),
              child: IconTheme(
                data: const IconThemeData(size: fontSize, color: textColor),
                // The inner DefaultTextStyle and IconTheme widgets define
                // InheritedThemes that captureAll() will wrap() around
                // TestRoute's IconTextBox child.
                child: DefaultTextStyle(
                  style: const TextStyle(fontSize: fontSize, color: textColor),
                  child: IconTheme(
                    data: const IconThemeData(size: iconSize, color: iconColor),
                    child: Builder(
                      builder: (BuildContext context) {
                        return GestureDetector(
                          behavior: HitTestBehavior.opaque,
                          onTap: () {
                            navigatorContext = context;
                            Navigator.of(context).push(
                              TestRoute(
                                useCaptureAll
                                  ? InheritedTheme.captureAll(context, const IconTextBox('Hello'))
                                  : const IconTextBox('Hello'),
                              ),
                            );
                          },
                          child: const IconTextBox('Tap'),
                        );
                      },
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      );
    }

    TextStyle getIconStyle() {
      return tester.widget<RichText>(
        find.descendant(
          of: find.byType(Icon),
          matching: find.byType(RichText),
        ),
      ).text.style!;
    }

    TextStyle getTextStyle(String text) {
      return tester.widget<RichText>(
        find.descendant(
          of: find.text(text),
          matching: find.byType(RichText),
        ),
      ).text.style!;
    }

    useCaptureAll = false;
    await tester.pumpWidget(buildFrame());
    expect(find.text('Tap'), findsOneWidget);
    expect(find.text('Hello'), findsNothing);
    expect(getTextStyle('Tap').color, textColor);
    expect(getTextStyle('Tap').fontSize, fontSize);
    expect(getIconStyle().color, iconColor);
    expect(getIconStyle().fontSize, iconSize);

    // Tap to show the TestRoute
    await tester.tap(find.text('Tap'));
    await tester.pumpAndSettle(); // route transition
    expect(find.text('Tap'), findsNothing);
    expect(find.text('Hello'), findsOneWidget);
    // The new route's text and icons will NOT inherit the DefaultTextStyle or
    // IconTheme values.
    expect(getTextStyle('Hello').color, isNot(textColor));
    expect(getTextStyle('Hello').fontSize, isNot(fontSize));
    expect(getIconStyle().color, isNot(iconColor));
    expect(getIconStyle().fontSize, isNot(iconSize));

    // Return to the home route
    useCaptureAll = true;
    Navigator.of(navigatorContext).pop();
    await tester.pumpAndSettle(); // route transition

    // Verify that all is the same as it was when the test started
    expect(find.text('Tap'), findsOneWidget);
    expect(find.text('Hello'), findsNothing);
    expect(getTextStyle('Tap').color, textColor);
    expect(getTextStyle('Tap').fontSize, fontSize);
    expect(getIconStyle().color, iconColor);
    expect(getIconStyle().fontSize, iconSize);

    // Tap to show the TestRoute. The test route's IconTextBox will have been
    // wrapped with InheritedTheme.captureAll().
    await tester.tap(find.text('Tap'));
    await tester.pumpAndSettle(); // route transition
    expect(find.text('Tap'), findsNothing);
    expect(find.text('Hello'), findsOneWidget);
    // The new route's text and icons will inherit the DefaultTextStyle or
    // IconTheme values because captureAll.
    expect(getTextStyle('Hello').color, textColor);
    expect(getTextStyle('Hello').fontSize, fontSize);
    expect(getIconStyle().color, iconColor);
    expect(getIconStyle().fontSize, iconSize);
  });

  testWidgets('InheritedTheme.captureAll() multiple IconTheme ancestors', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/39087

    const Color outerColor = Color(0xFF0000FF);
    const Color innerColor = Color(0xFF00FF00);
    const double iconSize = 48;
    final Key icon1 = UniqueKey();
    final Key icon2 = UniqueKey();

    await tester.pumpWidget(
      WidgetsApp(
        color: const Color(0xFFFFFFFF),
        onGenerateRoute: (RouteSettings settings) {
          return TestRoute(
            IconTheme(
              data: const IconThemeData(color: outerColor),
              child: IconTheme(
                data: const IconThemeData(size: iconSize, color: innerColor),
                child: Center(
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Icon(const IconData(0x41, fontFamily: 'Roboto'), key: icon1),
                      Builder(
                        builder: (BuildContext context) {
                          // The same IconThemes are visible from this context
                          // and the context that the widget returned by captureAll()
                          // is built in. So only the inner green IconTheme should
                          // apply to the icon, i.e. both icons will be big and green.
                          return InheritedTheme.captureAll(
                            context,
                            Icon(const IconData(0x41, fontFamily: 'Roboto'), key: icon2),
                          );
                        },
                      ),
                    ],
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );

    TextStyle getIconStyle(Key key) {
      return tester.widget<RichText>(
        find.descendant(
          of: find.byKey(key),
          matching: find.byType(RichText),
        ),
      ).text.style!;
    }

    expect(getIconStyle(icon1).color, innerColor);
    expect(getIconStyle(icon1).fontSize, iconSize);
    expect(getIconStyle(icon2).color, innerColor);
    expect(getIconStyle(icon2).fontSize, iconSize);
  });

  testWidgets('InheritedTheme.captureAll() multiple DefaultTextStyle ancestors', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/39087

    const Color textColor = Color(0xFF00FF00);

    await tester.pumpWidget(
      WidgetsApp(
        color: const Color(0xFFFFFFFF),
        onGenerateRoute: (RouteSettings settings) {
          return TestRoute(
            DefaultTextStyle(
              style: const TextStyle(fontSize: 48),
              child: DefaultTextStyle(
                style: const TextStyle(color: textColor),
                child: Row(
                  children: <Widget>[
                    const Text('Hello'),
                    Builder(
                      builder: (BuildContext context) {
                        return InheritedTheme.captureAll(context, const Text('World'));
                      },
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      ),
    );

    TextStyle getTextStyle(String text) {
      return tester.widget<RichText>(
        find.descendant(
          of: find.text(text),
          matching: find.byType(RichText),
        ),
      ).text.style!;
    }

    expect(getTextStyle('Hello').fontSize, null);
    expect(getTextStyle('Hello').color, textColor);
    expect(getTextStyle('World').fontSize, null);
    expect(getTextStyle('World').color, textColor);
  });
}
