// 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_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';

import 'webview_platform_test.mocks.dart';

void main() {
  setUp(() {
    WebViewPlatform.instance = MockWebViewPlatformWithMixin();
  });

  test('Cannot be implemented with `implements`', () {
    const PlatformNavigationDelegateCreationParams params =
        PlatformNavigationDelegateCreationParams();
    when(WebViewPlatform.instance!.createPlatformNavigationDelegate(params))
        .thenReturn(ImplementsPlatformNavigationDelegate());

    expect(() {
      PlatformNavigationDelegate(params);
      // In versions of `package:plugin_platform_interface` prior to fixing
      // https://github.com/flutter/flutter/issues/109339, an attempt to
      // implement a platform interface using `implements` would sometimes throw
      // a `NoSuchMethodError` and other times throw an `AssertionError`.  After
      // the issue is fixed, an `AssertionError` will always be thrown.  For the
      // purpose of this test, we don't really care what exception is thrown, so
      // just allow any exception.
    }, throwsA(anything));
  });

  test('Can be extended', () {
    const PlatformNavigationDelegateCreationParams params =
        PlatformNavigationDelegateCreationParams();
    when(WebViewPlatform.instance!.createPlatformNavigationDelegate(params))
        .thenReturn(ExtendsPlatformNavigationDelegate(params));

    expect(PlatformNavigationDelegate(params), isNotNull);
  });

  test('Can be mocked with `implements`', () {
    const PlatformNavigationDelegateCreationParams params =
        PlatformNavigationDelegateCreationParams();
    when(WebViewPlatform.instance!.createPlatformNavigationDelegate(params))
        .thenReturn(MockNavigationDelegate());

    expect(PlatformNavigationDelegate(params), isNotNull);
  });

  test(
      // ignore: lines_longer_than_80_chars
      'Default implementation of setOnNavigationRequest should throw unimplemented error',
      () {
    final PlatformNavigationDelegate callbackDelegate =
        ExtendsPlatformNavigationDelegate(
            const PlatformNavigationDelegateCreationParams());

    expect(
      () => callbackDelegate.setOnNavigationRequest(
          (NavigationRequest navigationRequest) => NavigationDecision.navigate),
      throwsUnimplementedError,
    );
  });

  test(
      // ignore: lines_longer_than_80_chars
      'Default implementation of setOnPageStarted should throw unimplemented error',
      () {
    final PlatformNavigationDelegate callbackDelegate =
        ExtendsPlatformNavigationDelegate(
            const PlatformNavigationDelegateCreationParams());

    expect(
      () => callbackDelegate.setOnPageStarted((String url) {}),
      throwsUnimplementedError,
    );
  });

  test(
      // ignore: lines_longer_than_80_chars
      'Default implementation of setOnPageFinished should throw unimplemented error',
      () {
    final PlatformNavigationDelegate callbackDelegate =
        ExtendsPlatformNavigationDelegate(
            const PlatformNavigationDelegateCreationParams());

    expect(
      () => callbackDelegate.setOnPageFinished((String url) {}),
      throwsUnimplementedError,
    );
  });

  test(
      // ignore: lines_longer_than_80_chars
      'Default implementation of setOnProgress should throw unimplemented error',
      () {
    final PlatformNavigationDelegate callbackDelegate =
        ExtendsPlatformNavigationDelegate(
            const PlatformNavigationDelegateCreationParams());

    expect(
      () => callbackDelegate.setOnProgress((int progress) {}),
      throwsUnimplementedError,
    );
  });

  test(
      // ignore: lines_longer_than_80_chars
      'Default implementation of setOnWebResourceError should throw unimplemented error',
      () {
    final PlatformNavigationDelegate callbackDelegate =
        ExtendsPlatformNavigationDelegate(
            const PlatformNavigationDelegateCreationParams());

    expect(
      () => callbackDelegate.setOnWebResourceError((WebResourceError error) {}),
      throwsUnimplementedError,
    );
  });
}

class MockWebViewPlatformWithMixin extends MockWebViewPlatform
    with
        // ignore: prefer_mixin
        MockPlatformInterfaceMixin {}

class ImplementsPlatformNavigationDelegate
    implements PlatformNavigationDelegate {
  @override
  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class MockNavigationDelegate extends Mock
    with
        // ignore: prefer_mixin
        MockPlatformInterfaceMixin
    implements
        PlatformNavigationDelegate {}

class ExtendsPlatformNavigationDelegate extends PlatformNavigationDelegate {
  ExtendsPlatformNavigationDelegate(
      PlatformNavigationDelegateCreationParams params)
      : super.implementation(params);
}
