// 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.

// @dart = 2.8

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;
    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);
  });
}
