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

// @dart = 2.6
@TestOn('!safari')
// TODO(nurhan): https://github.com/flutter/flutter/issues/51169

import 'dart:async';
import 'dart:html' as html;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:ui/src/engine.dart';

import '../spy.dart';

TestLocationStrategy _strategy;
TestLocationStrategy get strategy => _strategy;
set strategy(TestLocationStrategy newStrategy) {
  window.locationStrategy = _strategy = newStrategy;
}

const Map<String, bool> originState = <String, bool>{'origin': true};
const Map<String, bool> flutterState = <String, bool>{'flutter': true};

const MethodCodec codec = JSONMethodCodec();

void emptyCallback(ByteData date) {}

void main() {
  group('$BrowserHistory', () {
    final PlatformMessagesSpy spy = PlatformMessagesSpy();

    setUp(() {
      spy.setUp();
    });

    tearDown(() {
      spy.tearDown();
      strategy = null;
    });

    test('basic setup works', () {
      strategy = TestLocationStrategy.fromEntry(
          TestHistoryEntry('initial state', null, '/initial'));

      // There should be two entries: origin and flutter.
      expect(strategy.history, hasLength(2));

      // The origin entry is setup but its path should remain unchanged.
      final TestHistoryEntry originEntry = strategy.history[0];
      expect(originEntry.state, originState);
      expect(originEntry.url, '/initial');

      // The flutter entry is pushed and its path should be derived from the
      // origin entry.
      final TestHistoryEntry flutterEntry = strategy.history[1];
      expect(flutterEntry.state, flutterState);
      expect(flutterEntry.url, '/initial');

      // The flutter entry is the current entry.
      expect(strategy.currentEntry, flutterEntry);
    },
        // TODO(nurhan): https://github.com/flutter/flutter/issues/50836
        skip: browserEngine == BrowserEngine.edge);

    test('browser back button pops routes correctly', () async {
      strategy =
          TestLocationStrategy.fromEntry(TestHistoryEntry(null, null, '/home'));

      // Initially, we should be on the flutter entry.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');

      pushRoute('/page1');
      // The number of entries shouldn't change.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      // But the url of the current entry (flutter entry) should be updated.
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page1');

      // No platform messages have been sent so far.
      expect(spy.messages, isEmpty);
      // Clicking back should take us to page1.
      await strategy.back();
      // First, the framework should've received a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      // We still have 2 entries.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      // The url of the current entry (flutter entry) should go back to /home.
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');
    },
        // TODO(nurhan): https://github.com/flutter/flutter/issues/50836
        skip: browserEngine == BrowserEngine.edge);

    test('multiple browser back clicks', () async {
      strategy =
          TestLocationStrategy.fromEntry(TestHistoryEntry(null, null, '/home'));

      pushRoute('/page1');
      pushRoute('/page2');

      // Make sure we are on page2.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page2');

      // Back to page1.
      await strategy.back();
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `routePopped` platform message.
      popRoute('/page1');
      // 3. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page1');

      // Back to home.
      await strategy.back();
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `routePopped` platform message.
      popRoute('/home');
      // 3. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');

      // The next browser back will exit the app.
      await strategy.back();
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `SystemNavigator.pop` platform message
      // because there are no more routes to pop.
      await systemNavigatorPop();
      // 3. The active entry doesn't belong to our history anymore because we
      // navigated past it.
      expect(strategy.currentEntryIndex, -1);
    },
        // TODO(nurhan): https://github.com/flutter/flutter/issues/50836
        skip: browserEngine == BrowserEngine.edge ||
            browserEngine == BrowserEngine.webkit);

    test('handle user-provided url', () async {
      strategy =
          TestLocationStrategy.fromEntry(TestHistoryEntry(null, null, '/home'));

      await _strategy.simulateUserTypingUrl('/page3');
      // This delay is necessary to wait for [BrowserHistory] because it
      // performs a `back` operation which results in a new event loop.
      await Future<void>.delayed(Duration.zero);
      // 1. The engine sends a `pushRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRoute');
      expect(spy.messages[0].methodArguments, '/page3');
      spy.messages.clear();
      // 2. The framework sends a `routePushed` platform message.
      pushRoute('/page3');
      // 3. The history state should reflect that /page3 is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page3');

      // Back to home.
      await strategy.back();
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `routePopped` platform message.
      popRoute('/home');
      // 3. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');
    },
        // TODO(nurhan): https://github.com/flutter/flutter/issues/50836
        skip: browserEngine == BrowserEngine.edge);

    test('user types unknown url', () async {
      strategy =
          TestLocationStrategy.fromEntry(TestHistoryEntry(null, null, '/home'));

      await _strategy.simulateUserTypingUrl('/unknown');
      // This delay is necessary to wait for [BrowserHistory] because it
      // performs a `back` operation which results in a new event loop.
      await Future<void>.delayed(Duration.zero);
      // 1. The engine sends a `pushRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRoute');
      expect(spy.messages[0].methodArguments, '/unknown');
      spy.messages.clear();
      // 2. The framework doesn't recognize the route name and ignores it.
      // 3. The history state should reflect that /home is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');
    },
        // TODO(nurhan): https://github.com/flutter/flutter/issues/50836
        skip: browserEngine == BrowserEngine.edge);
  });

  group('$HashLocationStrategy', () {
    TestPlatformLocation location;

    setUp(() {
      location = TestPlatformLocation();
    });

    tearDown(() {
      location = null;
    });

    test('leading slash is optional', () {
      final HashLocationStrategy strategy = HashLocationStrategy(location);

      location.hash = '#/';
      expect(strategy.path, '/');

      location.hash = '#/foo';
      expect(strategy.path, '/foo');

      location.hash = '#foo';
      expect(strategy.path, 'foo');
    });

    test('path should not be empty', () {
      final HashLocationStrategy strategy = HashLocationStrategy(location);

      location.hash = '';
      expect(strategy.path, '/');

      location.hash = '#';
      expect(strategy.path, '/');
    });
  });
}

void pushRoute(String routeName) {
  window.sendPlatformMessage(
    'flutter/navigation',
    codec.encodeMethodCall(MethodCall(
      'routePushed',
      <String, dynamic>{'previousRouteName': '/foo', 'routeName': routeName},
    )),
    emptyCallback,
  );
}

void replaceRoute(String routeName) {
  window.sendPlatformMessage(
    'flutter/navigation',
    codec.encodeMethodCall(MethodCall(
      'routeReplaced',
      <String, dynamic>{'previousRouteName': '/foo', 'routeName': routeName},
    )),
    emptyCallback,
  );
}

void popRoute(String previousRouteName) {
  window.sendPlatformMessage(
    'flutter/navigation',
    codec.encodeMethodCall(MethodCall(
      'routePopped',
      <String, dynamic>{
        'previousRouteName': previousRouteName,
        'routeName': '/foo'
      },
    )),
    emptyCallback,
  );
}

Future<void> systemNavigatorPop() {
  final Completer<void> completer = Completer<void>();
  window.sendPlatformMessage(
    'flutter/platform',
    codec.encodeMethodCall(MethodCall('SystemNavigator.pop')),
    (_) => completer.complete(),
  );
  return completer.future;
}

/// A mock implementation of [PlatformLocation] that doesn't access the browser.
class TestPlatformLocation extends PlatformLocation {
  String pathname;
  String search;
  String hash;

  void onPopState(html.EventListener fn) {
    throw UnimplementedError();
  }

  void offPopState(html.EventListener fn) {
    throw UnimplementedError();
  }

  void onHashChange(html.EventListener fn) {
    throw UnimplementedError();
  }

  void offHashChange(html.EventListener fn) {
    throw UnimplementedError();
  }

  void pushState(dynamic state, String title, String url) {
    throw UnimplementedError();
  }

  void replaceState(dynamic state, String title, String url) {
    throw UnimplementedError();
  }

  void back() {
    throw UnimplementedError();
  }
}
