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

void main() {
  testWidgets('Simple router basic functionality - synchronized', (WidgetTester tester) async {
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider();
    provider.value = const RouteInformation(
      location: 'initial',
    );
    await tester.pumpWidget(buildBoilerPlate(
      Router<RouteInformation>(
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: SimpleRouterDelegate(
          builder: (BuildContext context, RouteInformation information) {
            return Text(information.location);
          }
        ),
      )
    ));
    expect(find.text('initial'), findsOneWidget);

    provider.value = const RouteInformation(
      location: 'update',
    );
    await tester.pump();
    expect(find.text('initial'), findsNothing);
    expect(find.text('update'), findsOneWidget);
  });

  testWidgets('Simple router basic functionality - asynchronized', (WidgetTester tester) async {
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider();
    provider.value = const RouteInformation(
      location: 'initial',
    );
    final SimpleAsyncRouteInformationParser parser = SimpleAsyncRouteInformationParser();
    final SimpleAsyncRouterDelegate delegate = SimpleAsyncRouterDelegate(
      builder: (BuildContext context, RouteInformation information) {
        if (information == null)
          return const Text('waiting');
        return Text(information.location);
      }
    );
    await tester.runAsync(() async {
      await tester.pumpWidget(buildBoilerPlate(
        Router<RouteInformation>(
          routeInformationProvider: provider,
          routeInformationParser: parser,
          routerDelegate: delegate,
        )
      ));
      // Future has not yet completed.
      expect(find.text('waiting'), findsOneWidget);

      await parser.parsingFuture;
      await delegate.setNewRouteFuture;
      await tester.pump();
      expect(find.text('initial'), findsOneWidget);

      provider.value = const RouteInformation(
        location: 'update',
      );
      await tester.pump();
      // Future has not yet completed.
      expect(find.text('initial'), findsOneWidget);

      await parser.parsingFuture;
      await delegate.setNewRouteFuture;
      await tester.pump();
      expect(find.text('update'), findsOneWidget);
    });
  });

  testWidgets('Simple router can handle pop route', (WidgetTester tester) async {
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider();
    provider.value = const RouteInformation(
      location: 'initial',
    );
    final BackButtonDispatcher dispatcher = RootBackButtonDispatcher();

    await tester.pumpWidget(buildBoilerPlate(
      Router<RouteInformation>(
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: SimpleRouterDelegate(
          builder: (BuildContext context, RouteInformation information) {
            return Text(information.location);
          },
          onPopRoute: () {
            provider.value = const RouteInformation(
              location: 'popped',
            );
            return SynchronousFuture<bool>(true);
          }
        ),
        backButtonDispatcher: dispatcher,
      )
    ));
    expect(find.text('initial'), findsOneWidget);

    bool result = false;
    // SynchronousFuture should complete immediately.
    dispatcher.invokeCallback(SynchronousFuture<bool>(false))
      .then((bool data) {
        result = data;
      });
    expect(result, isTrue);

    await tester.pump();
    expect(find.text('popped'), findsOneWidget);
  });

  testWidgets('PopNavigatorRouterDelegateMixin works', (WidgetTester tester) async {
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider();
    provider.value = const RouteInformation(
      location: 'initial',
    );
    final BackButtonDispatcher dispatcher = RootBackButtonDispatcher();
    final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
      builder: (BuildContext context, RouteInformation information) {
        return Text(information.location);
      },
      onPopPage: (Route<void> route, void result) {
        provider.value = const RouteInformation(
          location: 'popped',
        );
        return route.didPop(result);
      }
    );
    await tester.pumpWidget(buildBoilerPlate(
      Router<RouteInformation>(
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: delegate,
        backButtonDispatcher: dispatcher,
      )
    ));
    expect(find.text('initial'), findsOneWidget);

    // Pushes a nameless route.
    showDialog<void>(
      useRootNavigator: false,
      context: delegate.navigatorKey.currentContext,
      builder: (BuildContext context) => const Text('dialog')
    );
    await tester.pumpAndSettle();
    expect(find.text('dialog'), findsOneWidget);

    // Pops the nameless route and makes sure the initial page is shown.
    bool result = false;
    result = await dispatcher.invokeCallback(SynchronousFuture<bool>(false));
    expect(result, isTrue);

    await tester.pumpAndSettle();
    expect(find.text('initial'), findsOneWidget);
    expect(find.text('dialog'), findsNothing);

    // Pops one more time.
    result = false;
    result = await dispatcher.invokeCallback(SynchronousFuture<bool>(false));
    expect(result, isTrue);
    await tester.pumpAndSettle();
    expect(find.text('popped'), findsOneWidget);
  });

  testWidgets('Nested routers back button dispatcher works', (WidgetTester tester) async {
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider();
    provider.value = const RouteInformation(
      location: 'initial',
    );
    final BackButtonDispatcher outerDispatcher = RootBackButtonDispatcher();
    await tester.pumpWidget(buildBoilerPlate(
      Router<RouteInformation>(
        backButtonDispatcher: outerDispatcher,
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: SimpleRouterDelegate(
          builder: (BuildContext context, RouteInformation information) {
            final BackButtonDispatcher innerDispatcher = ChildBackButtonDispatcher(outerDispatcher);
            innerDispatcher.takePriority();
            // Creates the sub-router.
            return Router<RouteInformation>(
              backButtonDispatcher: innerDispatcher,
              routerDelegate: SimpleRouterDelegate(
                builder: (BuildContext context, RouteInformation innerInformation) {
                  return Text(information.location);
                },
                onPopRoute: () {
                  provider.value = const RouteInformation(
                    location: 'popped inner',
                  );
                  return SynchronousFuture<bool>(true);
                },
              ),
            );
          },
          onPopRoute: () {
            provider.value = const RouteInformation(
              location: 'popped outter',
            );
            return SynchronousFuture<bool>(true);
          }
        ),
      )
    ));
    expect(find.text('initial'), findsOneWidget);

    // The outer dispatcher should trigger the pop on the inner router.
    bool result = false;
    result = await outerDispatcher.invokeCallback(SynchronousFuture<bool>(false));
    expect(result, isTrue);
    await tester.pump();
    expect(find.text('popped inner'), findsOneWidget);
  });

  testWidgets('Nested router back button dispatcher works for multiple children', (WidgetTester tester) async {
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider();
    provider.value = const RouteInformation(
      location: 'initial',
    );
    final BackButtonDispatcher outerDispatcher = RootBackButtonDispatcher();
    final BackButtonDispatcher innerDispatcher1 = ChildBackButtonDispatcher(outerDispatcher);
    final BackButtonDispatcher innerDispatcher2 = ChildBackButtonDispatcher(outerDispatcher);
    await tester.pumpWidget(buildBoilerPlate(
      Router<RouteInformation>(
        backButtonDispatcher: outerDispatcher,
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: SimpleRouterDelegate(
          builder: (BuildContext context, RouteInformation information) {
            // Creates the sub-router.
            return Column(
              children: <Widget>[
                Text(information.location),
                Router<RouteInformation>(
                  backButtonDispatcher: innerDispatcher1,
                  routerDelegate: SimpleRouterDelegate(
                    builder: (BuildContext context, RouteInformation innerInformation) {
                      return Container();
                    },
                    onPopRoute: () {
                      provider.value = const RouteInformation(
                        location: 'popped inner1',
                      );
                      return SynchronousFuture<bool>(true);
                    },
                  ),
                ),
                Router<RouteInformation>(
                  backButtonDispatcher: innerDispatcher2,
                  routerDelegate: SimpleRouterDelegate(
                    builder: (BuildContext context, RouteInformation innerInformation) {
                      return Container();
                    },
                    onPopRoute: () {
                      provider.value = const RouteInformation(
                        location: 'popped inner2',
                      );
                      return SynchronousFuture<bool>(true);
                    },
                  ),
                ),
              ],
            );
          },
          onPopRoute: () {
            provider.value = const RouteInformation(
              location: 'popped outter',
            );
            return SynchronousFuture<bool>(true);
          }
        ),
      )
    ));
    expect(find.text('initial'), findsOneWidget);

    // If none of the children have taken the priority, the root router handles
    // the pop.
    bool result = false;
    result = await outerDispatcher.invokeCallback(SynchronousFuture<bool>(false));
    expect(result, isTrue);
    await tester.pump();
    expect(find.text('popped outter'), findsOneWidget);

    innerDispatcher1.takePriority();
    result = false;
    result = await outerDispatcher.invokeCallback(SynchronousFuture<bool>(false));
    expect(result, isTrue);
    await tester.pump();
    expect(find.text('popped inner1'), findsOneWidget);

    // The last child dispatcher that took priority handles the pop.
    innerDispatcher2.takePriority();
    result = false;
    result = await outerDispatcher.invokeCallback(SynchronousFuture<bool>(false));
    expect(result, isTrue);
    await tester.pump();
    expect(find.text('popped inner2'), findsOneWidget);
  });

  testWidgets('router does report URL change correctly', (WidgetTester tester) async {
    RouteInformation reportedRouteInformation;
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider(
      onRouterReport: (RouteInformation information) {
        // Makes sure we only report once after manually cleaning up.
        expect(reportedRouteInformation, isNull);
        reportedRouteInformation = information;
      }
    );
    final SimpleRouterDelegate delegate = SimpleRouterDelegate(
      reportConfiguration: true,
      builder: (BuildContext context, RouteInformation information) {
        return Text(information.location);
      }
    );
    delegate.onPopRoute = () {
      delegate.routeInformation = const RouteInformation(
        location: 'popped',
      );
      return SynchronousFuture<bool>(true);
    };
    final BackButtonDispatcher outerDispatcher = RootBackButtonDispatcher();

    provider.value = const RouteInformation(
      location: 'initial',
    );

    await tester.pumpWidget(buildBoilerPlate(
      Router<RouteInformation>(
        backButtonDispatcher: outerDispatcher,
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: delegate,
      )
    ));
    expect(find.text('initial'), findsOneWidget);
    expect(reportedRouteInformation, isNull);
    delegate.routeInformation = const RouteInformation(
      location: 'update',
    );
    await tester.pump();
    expect(find.text('initial'), findsNothing);
    expect(find.text('update'), findsOneWidget);
    expect(reportedRouteInformation.location, 'update');

    // The router should not report if only state changes.
    reportedRouteInformation = null;
    delegate.routeInformation = const RouteInformation(
      location: 'update',
      state: 'another state',
    );
    await tester.pump();
    expect(find.text('update'), findsOneWidget);
    expect(reportedRouteInformation, isNull);

    reportedRouteInformation = null;
    bool result = false;
    result = await outerDispatcher.invokeCallback(SynchronousFuture<bool>(false));
    expect(result, isTrue);
    await tester.pump();
    expect(find.text('popped'), findsOneWidget);
    expect(reportedRouteInformation.location, 'popped');
  });

  testWidgets('router can be forced to recognize or ignore navigating events', (WidgetTester tester) async {
    RouteInformation reportedRouteInformation;
    bool isNavigating = false;
    RouteInformation nextRouteInformation;
    final SimpleRouteInformationProvider provider = SimpleRouteInformationProvider(
      onRouterReport: (RouteInformation information) {
        // Makes sure we only report once after manually cleaning up.
        expect(reportedRouteInformation, isNull);
        reportedRouteInformation = information;
      }
    );
    provider.value = const RouteInformation(
      location: 'initial',
    );
    final SimpleRouterDelegate delegate = SimpleRouterDelegate(reportConfiguration: true);
    delegate.builder = (BuildContext context, RouteInformation information) {
      return ElevatedButton(
        child: Text(information.location),
        onPressed: () {
          if (isNavigating) {
            Router.navigate(context, () {
              if (delegate.routeInformation != nextRouteInformation)
                delegate.routeInformation = nextRouteInformation;
            });
          } else {
            Router.neglect(context, () {
              if (delegate.routeInformation != nextRouteInformation)
                delegate.routeInformation = nextRouteInformation;
            });
          }
        },
      );
    };
    final BackButtonDispatcher outerDispatcher = RootBackButtonDispatcher();

    await tester.pumpWidget(buildBoilerPlate(
      Router<RouteInformation>(
        backButtonDispatcher: outerDispatcher,
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: delegate,
      )
    ));
    expect(find.text('initial'), findsOneWidget);
    expect(reportedRouteInformation, isNull);

    nextRouteInformation = const RouteInformation(
      location: 'update',
    );
    await tester.tap(find.byType(ElevatedButton));
    await tester.pump();
    expect(find.text('initial'), findsNothing);
    expect(find.text('update'), findsOneWidget);
    expect(reportedRouteInformation, isNull);

    isNavigating = true;
    // This should not trigger any real navigating event because the
    // nextRouteInformation does not change. However, the router should still
    // report a route information because isNavigating = true.
    await tester.tap(find.byType(ElevatedButton));
    await tester.pump();
    expect(reportedRouteInformation.location, 'update');
  });

  testWidgets('PlatformRouteInformationProvider works', (WidgetTester tester) async {
    final RouteInformationProvider provider = PlatformRouteInformationProvider(
      initialRouteInformation: const RouteInformation(
        location: 'initial',
      ),
    );
    final SimpleRouterDelegate delegate = SimpleRouterDelegate(
      builder: (BuildContext context, RouteInformation information) {
        final List<Widget> children = <Widget>[];
        if (information.location != null)
          children.add(Text(information.location));
        if (information.state != null)
          children.add(Text(information.state.toString()));
        return Column(
          children: children,
        );
      }
    );

    await tester.pumpWidget(MaterialApp.router(
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: delegate,
    ));
    expect(find.text('initial'), findsOneWidget);

    // Pushes through the `pushRouteInformation` in the navigation method channel.
    const Map<String, dynamic> testRouteInformation = <String, dynamic>{
      'location': 'testRouteName',
      'state': 'state',
    };
    final ByteData routerMessage = const JSONMethodCodec().encodeMethodCall(
      const MethodCall('pushRouteInformation', testRouteInformation)
    );
    await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', routerMessage, (_) { });
    await tester.pump();
    expect(find.text('testRouteName'), findsOneWidget);
    expect(find.text('state'), findsOneWidget);

    // Pushes through the `pushRoute` in the navigation method channel.
    const String testRouteName = 'newTestRouteName';
    final ByteData message = const JSONMethodCodec().encodeMethodCall(
      const MethodCall('pushRoute', testRouteName));
    await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
    await tester.pump();
    expect(find.text('newTestRouteName'), findsOneWidget);
  });

  testWidgets('RootBackButtonDispatcher works', (WidgetTester tester) async {
    final BackButtonDispatcher outerDispatcher = RootBackButtonDispatcher();
    final RouteInformationProvider provider = PlatformRouteInformationProvider(
      initialRouteInformation: const RouteInformation(
        location: 'initial',
      ),
    );
    final SimpleRouterDelegate delegate = SimpleRouterDelegate(
      reportConfiguration: true,
      builder: (BuildContext context, RouteInformation information) {
        return Text(information.location);
      }
    );
    delegate.onPopRoute = () {
      delegate.routeInformation = const RouteInformation(
        location: 'popped',
      );
      return SynchronousFuture<bool>(true);
    };

    await tester.pumpWidget(MaterialApp.router(
      backButtonDispatcher: outerDispatcher,
      routeInformationProvider: provider,
      routeInformationParser: SimpleRouteInformationParser(),
      routerDelegate: delegate,
    ));
    expect(find.text('initial'), findsOneWidget);

    // Pop route through the message channel.
    final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
    await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
    await tester.pump();
    expect(find.text('popped'), findsOneWidget);
  });
}

Widget buildBoilerPlate(Widget child) {
  return MaterialApp(
    home: Scaffold(
      body: child,
    ),
  );
}

typedef SimpleRouterDelegateBuilder = Widget Function(BuildContext, RouteInformation);
typedef SimpleRouterDelegatePopRoute = Future<bool> Function();
typedef SimpleNavigatorRouterDelegatePopPage<T> = bool Function(Route<T> route, T result);
typedef RouterReportRouterInformation = void Function(RouteInformation);

class SimpleRouteInformationParser extends RouteInformationParser<RouteInformation> {
  SimpleRouteInformationParser();

  @override
  Future<RouteInformation> parseRouteInformation(RouteInformation information) {
    return SynchronousFuture<RouteInformation>(information);
  }

  @override
  RouteInformation restoreRouteInformation(RouteInformation configuration) {
    return configuration;
  }
}

class SimpleRouterDelegate extends RouterDelegate<RouteInformation> with ChangeNotifier {
  SimpleRouterDelegate({
    this.builder,
    this.onPopRoute,
    this.reportConfiguration = false,
  });

  RouteInformation get routeInformation => _routeInformation;
  RouteInformation _routeInformation;
  set routeInformation(RouteInformation newValue) {
    _routeInformation = newValue;
    notifyListeners();
  }

  SimpleRouterDelegateBuilder builder;
  SimpleRouterDelegatePopRoute onPopRoute;
  final bool reportConfiguration;

  @override
  RouteInformation get currentConfiguration {
    if (reportConfiguration)
      return routeInformation;
    return null;
  }

  @override
  Future<void> setNewRoutePath(RouteInformation configuration) {
    _routeInformation = configuration;
    return SynchronousFuture<void>(null);
  }

  @override
  Future<bool> popRoute() {
    if (onPopRoute != null)
      return onPopRoute();
    return SynchronousFuture<bool>(true);
  }

  @override
  Widget build(BuildContext context) => builder(context, routeInformation);
}

class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation> with PopNavigatorRouterDelegateMixin<RouteInformation>, ChangeNotifier {
  SimpleNavigatorRouterDelegate({
    @required this.builder,
    this.onPopPage,
  });

  @override
  GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  RouteInformation get routeInformation => _routeInformation;
  RouteInformation _routeInformation;
  set routeInformation(RouteInformation newValue) {
    _routeInformation = newValue;
    notifyListeners();
  }

  SimpleRouterDelegateBuilder builder;
  SimpleNavigatorRouterDelegatePopPage<void> onPopPage;

  @override
  Future<void> setNewRoutePath(RouteInformation configuration) {
    _routeInformation = configuration;
    return SynchronousFuture<void>(null);
  }

  bool _handlePopPage(Route<void> route, void data) {
    return onPopPage(route, data);
  }

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      onPopPage: _handlePopPage,
      pages: <Page<void>>[
        // We need at least two pages for the pop to propagate through.
        // Otherwise, the navigator will bubble the pop to the system navigator.
        MaterialPage<void>(
          builder: (BuildContext context) => const Text('base'),
        ),
        MaterialPage<void>(
          key: ValueKey<String>(routeInformation?.location),
          builder: (BuildContext context) => builder(context, routeInformation),
        )
      ],
    );
  }
}

class SimpleRouteInformationProvider extends RouteInformationProvider with ChangeNotifier {
  SimpleRouteInformationProvider({
    this.onRouterReport
  });

  RouterReportRouterInformation onRouterReport;

  @override
  RouteInformation get value => _value;
  RouteInformation _value;
  set value(RouteInformation newValue) {
    _value = newValue;
    notifyListeners();
  }

  @override
  void routerReportsNewRouteInformation(RouteInformation routeInformation) {
    if (onRouterReport != null)
      onRouterReport(routeInformation);
  }
}

class SimpleAsyncRouteInformationParser extends RouteInformationParser<RouteInformation> {
  SimpleAsyncRouteInformationParser();

  Future<RouteInformation> parsingFuture;

  @override
  Future<RouteInformation> parseRouteInformation(RouteInformation information) {
    return parsingFuture = Future<RouteInformation>.value(information);
  }

  @override
  RouteInformation restoreRouteInformation(RouteInformation configuration) {
    return configuration;
  }
}

class SimpleAsyncRouterDelegate extends RouterDelegate<RouteInformation> with ChangeNotifier{
  SimpleAsyncRouterDelegate({
    @required this.builder,
  });

  RouteInformation get routeInformation => _routeInformation;
  RouteInformation _routeInformation;
  set routeInformation(RouteInformation newValue) {
    _routeInformation = newValue;
    notifyListeners();
  }

  SimpleRouterDelegateBuilder builder;
  Future<void> setNewRouteFuture;

  @override
  Future<void> setNewRoutePath(RouteInformation configuration) {
    _routeInformation = configuration;
    return setNewRouteFuture = Future<void>.value();
  }

  @override
  Future<bool> popRoute() {
    return Future<bool>.value(true);
  }

  @override
  Widget build(BuildContext context) => builder(context, routeInformation);
}
