// Copyright 2013 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/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router/src/configuration.dart';
import 'package:go_router/src/match.dart';
import 'package:go_router/src/matching.dart';
import 'package:go_router/src/parser.dart';

void main() {
  Future<GoRouteInformationParser> createParser(
    WidgetTester tester, {
    required List<RouteBase> routes,
    int redirectLimit = 5,
    GoRouterRedirect? redirect,
  }) async {
    final GoRouter router = GoRouter(
      routes: routes,
      redirectLimit: redirectLimit,
      redirect: redirect,
    );
    await tester.pumpWidget(MaterialApp.router(
      routerConfig: router,
    ));
    return router.routeInformationParser;
  }

  testWidgets('GoRouteInformationParser can parse route',
      (WidgetTester tester) async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/',
        builder: (_, __) => const Placeholder(),
        routes: <GoRoute>[
          GoRoute(
            path: 'abc',
            builder: (_, __) => const Placeholder(),
          ),
        ],
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirectLimit: 100,
      redirect: (_, __) => null,
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));

    RouteMatchList matchesObj =
        await parser.parseRouteInformationWithDependencies(
            const RouteInformation(location: '/'), context);
    List<RouteMatch> matches = matchesObj.matches;
    expect(matches.length, 1);
    expect(matches[0].queryParams.isEmpty, isTrue);
    expect(matches[0].extra, isNull);
    expect(matches[0].fullUriString, '/');
    expect(matches[0].subloc, '/');
    expect(matches[0].route, routes[0]);

    final Object extra = Object();
    matchesObj = await parser.parseRouteInformationWithDependencies(
        RouteInformation(location: '/abc?def=ghi', state: extra), context);
    matches = matchesObj.matches;
    expect(matches.length, 2);
    expect(matches[0].queryParams.length, 1);
    expect(matches[0].queryParams['def'], 'ghi');
    expect(matches[0].extra, extra);
    expect(matches[0].fullUriString, '/?def=ghi');
    expect(matches[0].subloc, '/');
    expect(matches[0].route, routes[0]);

    expect(matches[1].queryParams.length, 1);
    expect(matches[1].queryParams['def'], 'ghi');
    expect(matches[1].extra, extra);
    expect(matches[1].fullUriString, '/abc?def=ghi');
    expect(matches[1].subloc, '/abc');
    expect(matches[1].route, routes[0].routes[0]);
  });

  test('GoRouteInformationParser can retrieve route by name', () async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/',
        builder: (_, __) => const Placeholder(),
        routes: <GoRoute>[
          GoRoute(
            path: 'abc',
            name: 'lowercase',
            builder: (_, __) => const Placeholder(),
          ),
          GoRoute(
            path: 'efg',
            name: 'camelCase',
            builder: (_, __) => const Placeholder(),
          ),
          GoRoute(
            path: 'hij',
            name: 'snake_case',
            builder: (_, __) => const Placeholder(),
          ),
        ],
      ),
    ];

    final RouteConfiguration configuration = RouteConfiguration(
      routes: routes,
      redirectLimit: 100,
      topRedirect: (_, __) => null,
      navigatorKey: GlobalKey<NavigatorState>(),
    );

    expect(configuration.namedLocation('lowercase'), '/abc');
    expect(configuration.namedLocation('LOWERCASE'), '/abc');
    expect(configuration.namedLocation('camelCase'), '/efg');
    expect(configuration.namedLocation('camelcase'), '/efg');
    expect(configuration.namedLocation('snake_case'), '/hij');
    expect(configuration.namedLocation('SNAKE_CASE'), '/hij');

    // With query parameters
    expect(configuration.namedLocation('lowercase'), '/abc');
    expect(
        configuration.namedLocation('lowercase',
            queryParams: const <String, String>{'q': '1'}),
        '/abc?q=1');
    expect(
        configuration.namedLocation('lowercase',
            queryParams: const <String, String>{'q': '1', 'g': '2'}),
        '/abc?q=1&g=2');
  });

  test(
      'GoRouteInformationParser can retrieve route by name with query parameters',
      () async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/',
        builder: (_, __) => const Placeholder(),
        routes: <GoRoute>[
          GoRoute(
            path: 'abc',
            name: 'routeName',
            builder: (_, __) => const Placeholder(),
          ),
        ],
      ),
    ];

    final RouteConfiguration configuration = RouteConfiguration(
      routes: routes,
      redirectLimit: 100,
      topRedirect: (_, __) => null,
      navigatorKey: GlobalKey<NavigatorState>(),
    );

    expect(
      configuration
          .namedLocation('routeName', queryParams: const <String, dynamic>{
        'q1': 'v1',
        'q2': <String>['v2', 'v3'],
      }),
      '/abc?q1=v1&q2=v2&q2=v3',
    );
  });

  testWidgets('GoRouteInformationParser returns error when unknown route',
      (WidgetTester tester) async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/',
        builder: (_, __) => const Placeholder(),
        routes: <GoRoute>[
          GoRoute(
            path: 'abc',
            builder: (_, __) => const Placeholder(),
          ),
        ],
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirectLimit: 100,
      redirect: (_, __) => null,
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));

    final RouteMatchList matchesObj =
        await parser.parseRouteInformationWithDependencies(
            const RouteInformation(location: '/def'), context);
    final List<RouteMatch> matches = matchesObj.matches;
    expect(matches.length, 1);
    expect(matches[0].queryParams.isEmpty, isTrue);
    expect(matches[0].extra, isNull);
    expect(matches[0].fullUriString, '/def');
    expect(matches[0].subloc, '/def');
    expect(matches[0].error!.toString(),
        'Exception: no routes for location: /def');
  });

  testWidgets('GoRouteInformationParser can work with route parameters',
      (WidgetTester tester) async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/',
        builder: (_, __) => const Placeholder(),
        routes: <GoRoute>[
          GoRoute(
            path: ':uid/family/:fid',
            builder: (_, __) => const Placeholder(),
          ),
        ],
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirectLimit: 100,
      redirect: (_, __) => null,
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));
    final RouteMatchList matchesObj =
        await parser.parseRouteInformationWithDependencies(
            const RouteInformation(location: '/123/family/456'), context);
    final List<RouteMatch> matches = matchesObj.matches;

    expect(matches.length, 2);
    expect(matches[0].queryParams.isEmpty, isTrue);
    expect(matches[0].extra, isNull);
    expect(matches[0].fullUriString, '/');
    expect(matches[0].subloc, '/');

    expect(matches[1].queryParams.isEmpty, isTrue);
    expect(matches[1].extra, isNull);
    expect(matches[1].fullUriString, '/123/family/456');
    expect(matches[1].subloc, '/123/family/456');
    expect(matches[1].encodedParams.length, 2);
    expect(matches[1].encodedParams['uid'], '123');
    expect(matches[1].encodedParams['fid'], '456');
  });

  testWidgets(
      'GoRouteInformationParser processes top level redirect when there is no match',
      (WidgetTester tester) async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/',
        builder: (_, __) => const Placeholder(),
        routes: <GoRoute>[
          GoRoute(
            path: ':uid/family/:fid',
            builder: (_, __) => const Placeholder(),
          ),
        ],
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirectLimit: 100,
      redirect: (BuildContext context, GoRouterState state) {
        if (state.location != '/123/family/345') {
          return '/123/family/345';
        }
        return null;
      },
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));
    final RouteMatchList matchesObj =
        await parser.parseRouteInformationWithDependencies(
            const RouteInformation(location: '/random/uri'), context);
    final List<RouteMatch> matches = matchesObj.matches;

    expect(matches.length, 2);
    expect(matches[0].fullUriString, '/');
    expect(matches[0].subloc, '/');

    expect(matches[1].fullUriString, '/123/family/345');
    expect(matches[1].subloc, '/123/family/345');
  });

  testWidgets(
      'GoRouteInformationParser can do route level redirect when there is a match',
      (WidgetTester tester) async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/',
        builder: (_, __) => const Placeholder(),
        routes: <GoRoute>[
          GoRoute(
            path: ':uid/family/:fid',
            builder: (_, __) => const Placeholder(),
          ),
          GoRoute(
            path: 'redirect',
            redirect: (_, __) => '/123/family/345',
            builder: (_, __) => throw UnimplementedError(),
          ),
        ],
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirectLimit: 100,
      redirect: (_, __) => null,
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));
    final RouteMatchList matchesObj =
        await parser.parseRouteInformationWithDependencies(
            const RouteInformation(location: '/redirect'), context);
    final List<RouteMatch> matches = matchesObj.matches;

    expect(matches.length, 2);
    expect(matches[0].fullUriString, '/');
    expect(matches[0].subloc, '/');

    expect(matches[1].fullUriString, '/123/family/345');
    expect(matches[1].subloc, '/123/family/345');
  });

  testWidgets(
      'GoRouteInformationParser throws an exception when route is malformed',
      (WidgetTester tester) async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/abc',
        builder: (_, __) => const Placeholder(),
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirectLimit: 100,
      redirect: (_, __) => null,
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));
    expect(() async {
      await parser.parseRouteInformationWithDependencies(
          const RouteInformation(location: '::Not valid URI::'), context);
    }, throwsA(isA<FormatException>()));
  });

  testWidgets(
      'GoRouteInformationParser returns an error if a redirect is detected.',
      (WidgetTester tester) async {
    final List<GoRoute> routes = <GoRoute>[
      GoRoute(
        path: '/abc',
        builder: (_, __) => const Placeholder(),
        redirect: (BuildContext context, GoRouterState state) => state.location,
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirect: (_, __) => null,
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));
    final RouteMatchList matchesObj =
        await parser.parseRouteInformationWithDependencies(
            const RouteInformation(location: '/abd'), context);
    final List<RouteMatch> matches = matchesObj.matches;

    expect(matches, hasLength(1));
    expect(matches.first.error, isNotNull);
  });

  testWidgets('Creates a match for ShellRoute', (WidgetTester tester) async {
    final List<RouteBase> routes = <RouteBase>[
      ShellRoute(
        builder: (BuildContext context, GoRouterState state, Widget child) {
          return Scaffold(
            body: child,
          );
        },
        routes: <RouteBase>[
          GoRoute(
            path: '/a',
            builder: (BuildContext context, GoRouterState state) {
              return const Scaffold(
                body: Text('Screen A'),
              );
            },
          ),
          GoRoute(
            path: '/b',
            builder: (BuildContext context, GoRouterState state) {
              return const Scaffold(
                body: Text('Screen B'),
              );
            },
          ),
        ],
      ),
    ];
    final GoRouteInformationParser parser = await createParser(
      tester,
      routes: routes,
      redirect: (_, __) => null,
    );

    final BuildContext context = tester.element(find.byType(Router<Object>));
    final RouteMatchList matchesObj =
        await parser.parseRouteInformationWithDependencies(
            const RouteInformation(location: '/a'), context);
    final List<RouteMatch> matches = matchesObj.matches;

    expect(matches, hasLength(2));
    expect(matches.first.error, isNull);
  });
}
