// 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 'dart:async';
import 'dart:html' as html;
import 'dart:js_util' as js_util;

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart' hide window;
import 'package:ui/ui.dart' as ui;

import 'engine/history_test.dart';
import 'matchers.dart';

const MethodCodec codec = JSONMethodCodec();

Map<String, dynamic> _tagStateWithSerialCount(dynamic state, int serialCount) {
  return <String, dynamic> {
    'serialCount': serialCount,
    'state': state,
  };
}

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  late EngineSingletonFlutterWindow window;

  setUpAll(() async {
    await initializeEngine();
  });

  setUp(() {
    window = EngineSingletonFlutterWindow(0, EnginePlatformDispatcher.instance);
  });

  tearDown(() async {
    await window.resetHistory();
  });

  test('window.defaultRouteName should work with JsUrlStrategy', () async {
    dynamic state = <dynamic, dynamic>{};
    final JsUrlStrategy jsUrlStrategy = JsUrlStrategy(
        getPath: allowInterop(() => '/initial'),
        getState: allowInterop(() => state),
        addPopStateListener: allowInterop((DomEventListener listener) => () {}),
        prepareExternalUrl: allowInterop((String value) => ''),
        pushState: allowInterop((Object? newState, String title, String url) {
          expect(newState is Map, true);
        }),
        replaceState: allowInterop((Object? newState, String title, String url) {
          expect(newState is Map, true);
          state = newState;
        }),
        go: allowInterop(([int? delta]) async {
          expect(delta, -1);
        }));
    final CustomUrlStrategy strategy =
        CustomUrlStrategy.fromJs(jsUrlStrategy);
    await window.debugInitializeHistory(strategy, useSingle: true);
    expect(window.defaultRouteName, '/initial');
  });

  test('window.defaultRouteName should not change', () async {
    final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
      const TestHistoryEntry('initial state', null, '/initial'),
    );
    await window.debugInitializeHistory(strategy, useSingle: true);
    expect(window.defaultRouteName, '/initial');

    // Changing the URL in the address bar later shouldn't affect [window.defaultRouteName].
    strategy.replaceState(null, '', '/newpath');
    expect(window.defaultRouteName, '/initial');
  });

  // window.defaultRouteName is now permanently decoupled from the history,
  // even in subsequent tests, because the PlatformDispatcher caches it.

  test('window.defaultRouteName should reset after navigation platform message',
      () async {
    await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
      // The URL here does not set the PlatformDispatcher's defaultRouteName,
      // since it got cached as soon as we read it above.
      const TestHistoryEntry('initial state', null, '/not-really-inital/THIS_IS_IGNORED'),
    ), useSingle: true);
    // Reading it multiple times should return the same value.
    expect(window.defaultRouteName, '/initial');
    expect(window.defaultRouteName, '/initial');

    final Completer<void> callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeUpdated',
        <String, dynamic>{'routeName': '/bar'},
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    // After a navigation platform message, the PlatformDispatcher's
    // defaultRouteName resets to "/".
    expect(window.defaultRouteName, '/');
  });

  // window.defaultRouteName is now '/'.

  test('can switch history mode', () async {
    Completer<void> callback;
    await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
      const TestHistoryEntry('initial state', null, '/initial'),
    ), useSingle: false);
    expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());

    Future<void> check<T>(String method, Object? arguments) async {
      callback = Completer<void>();
      window.sendPlatformMessage(
        'flutter/navigation',
        const JSONMethodCodec().encodeMethodCall(MethodCall(method, arguments)),
        (_) { callback.complete(); },
      );
      await callback.future;
      expect(window.browserHistory, isA<T>());
    }

    // These may be initialized as `null`
    // See https://github.com/flutter/flutter/issues/83158#issuecomment-847483010
    await check<SingleEntryBrowserHistory>('selectSingleEntryHistory', null); // -> single
    await check<MultiEntriesBrowserHistory>('selectMultiEntryHistory', null); // -> multi
    await check<SingleEntryBrowserHistory>('selectSingleEntryHistory', <String, dynamic>{}); // -> single
    await check<MultiEntriesBrowserHistory>('selectMultiEntryHistory', <String, dynamic>{}); // -> multi
    await check<SingleEntryBrowserHistory>('routeUpdated', <String, dynamic>{'routeName': '/bar'}); // -> single
    await check<SingleEntryBrowserHistory>('routeInformationUpdated', <String, dynamic>{'location': '/bar'}); // does not change mode
    await check<MultiEntriesBrowserHistory>('selectMultiEntryHistory', <String, dynamic>{}); // -> multi
    await check<MultiEntriesBrowserHistory>('routeInformationUpdated', <String, dynamic>{'location': '/bar'}); // does not change mode
  });

  test('handleNavigationMessage throws for route update methods called with null arguments',
      () async {
    expect(() async {
      await window.handleNavigationMessage(
        const JSONMethodCodec().encodeMethodCall(const MethodCall(
          'routeUpdated',
          null, // boom
        ))
      );
    }, throwsAssertionError);

    expect(() async {
      await window.handleNavigationMessage(
        const JSONMethodCodec().encodeMethodCall(const MethodCall(
          'routeInformationUpdated',
          null, // boom
        ))
      );
    }, throwsAssertionError);
  });

  test('handleNavigationMessage execute request in order.', () async {
    // Start with multi entries.
    await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
      const TestHistoryEntry('initial state', null, '/initial'),
    ), useSingle: false);
    expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());
    final List<String> executionOrder = <String>[];
    await window.handleNavigationMessage(
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'selectSingleEntryHistory',
        null,
      ))
    ).then<void>((bool data) {
      executionOrder.add('1');
    });
    await window.handleNavigationMessage(
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'selectMultiEntryHistory',
        null,
      ))
    ).then<void>((bool data) {
      executionOrder.add('2');
    });
    await window.handleNavigationMessage(
        const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'selectSingleEntryHistory',
        null,
      ))
    ).then<void>((bool data) {
      executionOrder.add('3');
    });
    await window.handleNavigationMessage(
        const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeInformationUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{
          'location': '/baz',
          'state': null,
        }, // boom
      ))
    ).then<void>((bool data) {
      executionOrder.add('4');
    });
    // The routeInformationUpdated should finish after the browser history
    // has been set to single entry.
    expect(executionOrder.length, 4);
    expect(executionOrder[0], '1');
    expect(executionOrder[1], '2');
    expect(executionOrder[2], '3');
    expect(executionOrder[3], '4');
  });

  test('should not throw when using nav1 and nav2 together',
      () async {
    await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
      const TestHistoryEntry('initial state', null, '/initial'),
    ), useSingle: false);
    expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());

    // routeUpdated resets the history type
    Completer<void> callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{'routeName': '/bar'},
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory, isA<SingleEntryBrowserHistory>());
    expect(window.browserHistory.urlStrategy!.getPath(), '/bar');

    // routeInformationUpdated does not
    callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeInformationUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{
          'location': '/baz',
          'state': null,
        },
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory, isA<SingleEntryBrowserHistory>());
    expect(window.browserHistory.urlStrategy!.getPath(), '/baz');

    // they can be interleaved safely
    await window.handleNavigationMessage(
        const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{'routeName': '/foo'},
      ))
    );
    expect(window.browserHistory, isA<SingleEntryBrowserHistory>());
    expect(window.browserHistory.urlStrategy!.getPath(), '/foo');
  });

  test('should not throw when state is complex json object',
      () async {
    // Regression test https://github.com/flutter/flutter/issues/87823.
    await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
      const TestHistoryEntry('initial state', null, '/initial'),
    ), useSingle: false);
    expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());

    // routeInformationUpdated does not
    final Completer<void> callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeInformationUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{
          'location': '/baz',
          'state': <String, dynamic>{
            'state1': true,
            'state2': 1,
            'state3': 'string',
            'state4': <String, dynamic> {
              'substate1': 1.0,
              'substate2': 'string2',
            }
          },
        },
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());
    expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
    final dynamic wrappedState = window.browserHistory.urlStrategy!.getState()!;
    final dynamic actualState = wrappedState['state'];
    expect(actualState['state1'], true);
    expect(actualState['state2'], 1);
    expect(actualState['state3'], 'string');
    expect(actualState['state4']['substate1'], 1.0);
    expect(actualState['state4']['substate2'], 'string2');
  });

  test('can replace in MultiEntriesBrowserHistory',
      () async {
    await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
      const TestHistoryEntry('initial state', null, '/initial'),
    ), useSingle: false);
    expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());

    Completer<void> callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeInformationUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{
          'location': '/baz',
          'state': '/state',
        },
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
    expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/state', 1));

    callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeInformationUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{
          'location': '/baz',
          'state': '/state1',
          'replace': true
        },
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
    expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/state1', 1));

    callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeInformationUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{
          'location': '/foo',
          'state': '/foostate1',
        },
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory.urlStrategy!.getPath(), '/foo');
    expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/foostate1', 2));

    await window.browserHistory.back();
    expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
    expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/state1', 1));
  });

  test('initialize browser history with default url strategy (single)', () async {
    // On purpose, we don't initialize history on the window. We want to let the
    // window to self-initialize when it receives a navigation message.

    // Without initializing history, the default route name should be
    // initialized to "/" in tests.
    expect(window.defaultRouteName, '/');

    final Completer<void> callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{'routeName': '/bar'},
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory, isA<SingleEntryBrowserHistory>());
    // The url strategy should've been set to the default, and the path
    // should've been correctly set to "/bar".
    expect(window.browserHistory.urlStrategy, isNot(isNull));
    expect(window.browserHistory.urlStrategy!.getPath(), '/bar');
  }, skip: true); // https://github.com/flutter/flutter/issues/50836

  test('initialize browser history with default url strategy (multiple)', () async {
    // On purpose, we don't initialize history on the window. We want to let the
    // window to self-initialize when it receives a navigation message.

    // Without initializing history, the default route name should be
    // initialized to "/" in tests.
    expect(window.defaultRouteName, '/');

    final Completer<void> callback = Completer<void>();
    window.sendPlatformMessage(
      'flutter/navigation',
      const JSONMethodCodec().encodeMethodCall(const MethodCall(
        'routeInformationUpdated',
        // ignore: prefer_const_literals_to_create_immutables
        <String, dynamic>{
          'location': '/baz',
          'state': null,
        },
      )),
      (_) { callback.complete(); },
    );
    await callback.future;
    expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());
    // The url strategy should've been set to the default, and the path
    // should've been correctly set to "/baz".
    expect(window.browserHistory.urlStrategy, isNot(isNull));
    expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
  }, skip: true); // https://github.com/flutter/flutter/issues/50836

  test('can disable location strategy', () async {
    // Disable URL strategy.
    expect(() => jsSetUrlStrategy(null), returnsNormally);
    // History should be initialized.
    expect(window.browserHistory, isNotNull);
    // But without a URL strategy.
    expect(window.browserHistory.urlStrategy, isNull);
    // Current path is always "/" in this case.
    expect(window.browserHistory.currentPath, '/');

    // Perform some navigation operations.
    await routeInformationUpdated('/foo/bar', null);
    // Path should not be updated because URL strategy is disabled.
    expect(window.browserHistory.currentPath, '/');
  }, skip: true);

  test('js interop throws on wrong type', () {
    expect(() => jsSetUrlStrategy(123), throwsA(anything));
    expect(() => jsSetUrlStrategy('foo'), throwsA(anything));
    expect(() => jsSetUrlStrategy(false), throwsA(anything));
  });

  test('cannot set url strategy after it is initialized', () async {
    final TestUrlStrategy testStrategy = TestUrlStrategy.fromEntry(
      const TestHistoryEntry('initial state', null, '/'),
    );
    await window.debugInitializeHistory(testStrategy, useSingle: true);

    expect(() => jsSetUrlStrategy(null), throwsA(isAssertionError));
  });

  test('cannot set url strategy more than once', () async {
    // First time is okay.
    expect(() => jsSetUrlStrategy(null), returnsNormally);
    // Second time is not allowed.
    expect(() => jsSetUrlStrategy(null), throwsA(isAssertionError));
  });

  // Regression test for https://github.com/flutter/flutter/issues/77817
  test('window.locale(s) are not nullable', () {
    // If the getters were nullable, these expressions would result in compiler errors.
    ui.window.locale.countryCode;
    ui.window.locales.first.countryCode;
  });
}

void jsSetUrlStrategy(dynamic strategy) {
  js_util.callMethod<void>(
    html.window,
    '_flutter_web_set_location_strategy',
    <dynamic>[strategy],
  );
}
