// 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:typed_data';

import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:webview_flutter_platform_interface/src/method_channel/webview_method_channel.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('Tests on `plugin.flutter.io/webview_<channel_id>` channel', () {
    const int channelId = 1;
    const MethodChannel channel =
        MethodChannel('plugins.flutter.io/webview_$channelId');
    final WebViewPlatformCallbacksHandler callbacksHandler =
        MockWebViewPlatformCallbacksHandler();
    final JavascriptChannelRegistry javascriptChannelRegistry =
        MockJavascriptChannelRegistry();

    final List<MethodCall> log = <MethodCall>[];
    channel.setMockMethodCallHandler((MethodCall methodCall) async {
      log.add(methodCall);

      switch (methodCall.method) {
        case 'currentUrl':
          return 'https://test.url';
        case 'canGoBack':
        case 'canGoForward':
          return true;
        case 'loadFile':
          if (methodCall.arguments == 'invalid file') {
            throw PlatformException(
                code: 'loadFile_failed',
                message: 'Failed loading file.',
                details: null);
          } else if (methodCall.arguments == 'some error') {
            throw PlatformException(
              code: 'some_error',
              message: 'Some error occurred.',
              details: null,
            );
          }
          return null;
        case 'loadFlutterAsset':
          if (methodCall.arguments == 'invalid key') {
            throw PlatformException(
              code: 'loadFlutterAsset_invalidKey',
              message: 'Failed loading asset.',
              details: null,
            );
          } else if (methodCall.arguments == 'some error') {
            throw PlatformException(
              code: 'some_error',
              message: 'Some error occurred.',
              details: null,
            );
          }
          return null;
        case 'runJavascriptReturningResult':
        case 'evaluateJavascript':
          return methodCall.arguments as String;
        case 'getScrollX':
          return 10;
        case 'getScrollY':
          return 20;
      }

      // Return null explicitly instead of relying on the implicit null
      // returned by the method channel if no return statement is specified.
      return null;
    });

    final MethodChannelWebViewPlatform webViewPlatform =
        MethodChannelWebViewPlatform(
      channelId,
      callbacksHandler,
      javascriptChannelRegistry,
    );

    tearDown(() {
      log.clear();
    });

    test('loadFile', () async {
      await webViewPlatform.loadFile(
        '/folder/asset.html',
      );

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadFile',
            arguments: '/folder/asset.html',
          ),
        ],
      );
    });

    test('loadFile with invalid file', () async {
      expect(
        () => webViewPlatform.loadFile('invalid file'),
        throwsA(
          isA<ArgumentError>().having(
            (ArgumentError error) => error.message,
            'message',
            'Failed loading file.',
          ),
        ),
      );
    });

    test('loadFile with some error.', () async {
      expect(
        () => webViewPlatform.loadFile('some error'),
        throwsA(
          isA<PlatformException>().having(
            (PlatformException error) => error.message,
            'message',
            'Some error occurred.',
          ),
        ),
      );
    });

    test('loadFlutterAsset', () async {
      await webViewPlatform.loadFlutterAsset(
        'folder/asset.html',
      );

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadFlutterAsset',
            arguments: 'folder/asset.html',
          ),
        ],
      );
    });

    test('loadFlutterAsset with empty key', () async {
      expect(() => webViewPlatform.loadFlutterAsset(''), throwsAssertionError);
    });

    test('loadFlutterAsset with invalid key', () async {
      expect(
        () => webViewPlatform.loadFlutterAsset('invalid key'),
        throwsA(
          isA<ArgumentError>().having(
            (ArgumentError error) => error.message,
            'message',
            'Failed loading asset.',
          ),
        ),
      );
    });

    test('loadFlutterAsset with some error.', () async {
      expect(
        () => webViewPlatform.loadFlutterAsset('some error'),
        throwsA(
          isA<PlatformException>().having(
            (PlatformException error) => error.message,
            'message',
            'Some error occurred.',
          ),
        ),
      );
    });

    test('loadHtmlString without base URL', () async {
      await webViewPlatform.loadHtmlString(
        'Test HTML string',
      );

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadHtmlString',
            arguments: <String, String?>{
              'html': 'Test HTML string',
              'baseUrl': null,
            },
          ),
        ],
      );
    });

    test('loadHtmlString without base URL', () async {
      await webViewPlatform.loadHtmlString(
        'Test HTML string',
        baseUrl: 'https://flutter.dev',
      );

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadHtmlString',
            arguments: <String, String?>{
              'html': 'Test HTML string',
              'baseUrl': 'https://flutter.dev',
            },
          ),
        ],
      );
    });

    test('loadUrl with headers', () async {
      await webViewPlatform.loadUrl(
        'https://test.url',
        const <String, String>{
          'Content-Type': 'text/plain',
          'Accept': 'text/html',
        },
      );

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadUrl',
            arguments: <String, dynamic>{
              'url': 'https://test.url',
              'headers': <String, String>{
                'Content-Type': 'text/plain',
                'Accept': 'text/html',
              },
            },
          ),
        ],
      );
    });

    test('loadUrl without headers', () async {
      await webViewPlatform.loadUrl(
        'https://test.url',
        null,
      );

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadUrl',
            arguments: <String, dynamic>{
              'url': 'https://test.url',
              'headers': null,
            },
          ),
        ],
      );
    });

    test('loadRequest', () async {
      await webViewPlatform.loadRequest(WebViewRequest(
        uri: Uri.parse('https://test.url'),
        method: WebViewRequestMethod.get,
      ));

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadRequest',
            arguments: <String, dynamic>{
              'request': <String, dynamic>{
                'uri': 'https://test.url',
                'method': 'get',
                'headers': <String, String>{},
                'body': null,
              }
            },
          ),
        ],
      );
    });

    test('loadRequest with optional parameters', () async {
      await webViewPlatform.loadRequest(WebViewRequest(
        uri: Uri.parse('https://test.url'),
        method: WebViewRequestMethod.get,
        headers: <String, String>{'foo': 'bar'},
        body: Uint8List.fromList('hello world'.codeUnits),
      ));

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'loadRequest',
            arguments: <String, dynamic>{
              'request': <String, dynamic>{
                'uri': 'https://test.url',
                'method': 'get',
                'headers': <String, String>{'foo': 'bar'},
                'body': 'hello world'.codeUnits,
              }
            },
          ),
        ],
      );
    });

    test('currentUrl', () async {
      final String? currentUrl = await webViewPlatform.currentUrl();

      expect(currentUrl, 'https://test.url');
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'currentUrl',
            arguments: null,
          ),
        ],
      );
    });

    test('canGoBack', () async {
      final bool canGoBack = await webViewPlatform.canGoBack();

      expect(canGoBack, true);
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'canGoBack',
            arguments: null,
          ),
        ],
      );
    });

    test('canGoForward', () async {
      final bool canGoForward = await webViewPlatform.canGoForward();

      expect(canGoForward, true);
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'canGoForward',
            arguments: null,
          ),
        ],
      );
    });

    test('goBack', () async {
      await webViewPlatform.goBack();

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'goBack',
            arguments: null,
          ),
        ],
      );
    });

    test('goForward', () async {
      await webViewPlatform.goForward();

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'goForward',
            arguments: null,
          ),
        ],
      );
    });

    test('reload', () async {
      await webViewPlatform.reload();

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'reload',
            arguments: null,
          ),
        ],
      );
    });

    test('clearCache', () async {
      await webViewPlatform.clearCache();

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'clearCache',
            arguments: null,
          ),
        ],
      );
    });

    test('updateSettings', () async {
      final WebSettings settings =
          WebSettings(userAgent: const WebSetting<String?>.of('Dart Test'));
      await webViewPlatform.updateSettings(settings);

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'updateSettings',
            arguments: <String, dynamic>{
              'userAgent': 'Dart Test',
            },
          ),
        ],
      );
    });

    test('updateSettings all parameters', () async {
      final WebSettings settings = WebSettings(
        userAgent: const WebSetting<String?>.of('Dart Test'),
        javascriptMode: JavascriptMode.disabled,
        hasNavigationDelegate: true,
        hasProgressTracking: true,
        debuggingEnabled: true,
        gestureNavigationEnabled: true,
        allowsInlineMediaPlayback: true,
        zoomEnabled: false,
      );
      await webViewPlatform.updateSettings(settings);

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'updateSettings',
            arguments: <String, dynamic>{
              'userAgent': 'Dart Test',
              'jsMode': 0,
              'hasNavigationDelegate': true,
              'hasProgressTracking': true,
              'debuggingEnabled': true,
              'gestureNavigationEnabled': true,
              'allowsInlineMediaPlayback': true,
              'zoomEnabled': false,
            },
          ),
        ],
      );
    });

    test('updateSettings without settings', () async {
      final WebSettings settings =
          WebSettings(userAgent: const WebSetting<String?>.absent());
      await webViewPlatform.updateSettings(settings);

      expect(
        log.isEmpty,
        true,
      );
    });

    test('evaluateJavascript', () async {
      final String evaluateJavascript =
          await webViewPlatform.evaluateJavascript(
        'This simulates some JavaScript code.',
      );

      expect('This simulates some JavaScript code.', evaluateJavascript);
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'evaluateJavascript',
            arguments: 'This simulates some JavaScript code.',
          ),
        ],
      );
    });

    test('runJavascript', () async {
      await webViewPlatform.runJavascript(
        'This simulates some JavaScript code.',
      );

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'runJavascript',
            arguments: 'This simulates some JavaScript code.',
          ),
        ],
      );
    });

    test('runJavascriptReturningResult', () async {
      final String evaluateJavascript =
          await webViewPlatform.runJavascriptReturningResult(
        'This simulates some JavaScript code.',
      );

      expect('This simulates some JavaScript code.', evaluateJavascript);
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'runJavascriptReturningResult',
            arguments: 'This simulates some JavaScript code.',
          ),
        ],
      );
    });

    test('addJavascriptChannels', () async {
      final Set<String> channels = <String>{'channel one', 'channel two'};
      await webViewPlatform.addJavascriptChannels(channels);

      expect(log, <Matcher>[
        isMethodCall(
          'addJavascriptChannels',
          arguments: <String>[
            'channel one',
            'channel two',
          ],
        ),
      ]);
    });

    test('addJavascriptChannels without channels', () async {
      final Set<String> channels = <String>{};
      await webViewPlatform.addJavascriptChannels(channels);

      expect(log, <Matcher>[
        isMethodCall(
          'addJavascriptChannels',
          arguments: <String>[],
        ),
      ]);
    });

    test('removeJavascriptChannels', () async {
      final Set<String> channels = <String>{'channel one', 'channel two'};
      await webViewPlatform.removeJavascriptChannels(channels);

      expect(log, <Matcher>[
        isMethodCall(
          'removeJavascriptChannels',
          arguments: <String>[
            'channel one',
            'channel two',
          ],
        ),
      ]);
    });

    test('removeJavascriptChannels without channels', () async {
      final Set<String> channels = <String>{};
      await webViewPlatform.removeJavascriptChannels(channels);

      expect(log, <Matcher>[
        isMethodCall(
          'removeJavascriptChannels',
          arguments: <String>[],
        ),
      ]);
    });

    test('getTitle', () async {
      final String? title = await webViewPlatform.getTitle();

      expect(title, null);
      expect(
        log,
        <Matcher>[
          isMethodCall('getTitle', arguments: null),
        ],
      );
    });

    test('scrollTo', () async {
      await webViewPlatform.scrollTo(10, 20);

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'scrollTo',
            arguments: <String, int>{
              'x': 10,
              'y': 20,
            },
          ),
        ],
      );
    });

    test('scrollBy', () async {
      await webViewPlatform.scrollBy(10, 20);

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'scrollBy',
            arguments: <String, int>{
              'x': 10,
              'y': 20,
            },
          ),
        ],
      );
    });

    test('getScrollX', () async {
      final int x = await webViewPlatform.getScrollX();

      expect(x, 10);
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'getScrollX',
            arguments: null,
          ),
        ],
      );
    });

    test('getScrollY', () async {
      final int y = await webViewPlatform.getScrollY();

      expect(y, 20);
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'getScrollY',
            arguments: null,
          ),
        ],
      );
    });

    test('backgroundColor is null by default', () {
      final CreationParams creationParams = CreationParams(
        webSettings: WebSettings(
          userAgent: const WebSetting<String?>.of('Dart Test'),
        ),
      );
      final Map<String, dynamic> creationParamsMap =
          MethodChannelWebViewPlatform.creationParamsToMap(creationParams);

      expect(creationParamsMap['backgroundColor'], null);
    });

    test('backgroundColor is converted to an int', () {
      const Color whiteColor = Color(0xFFFFFFFF);
      final CreationParams creationParams = CreationParams(
        backgroundColor: whiteColor,
        webSettings: WebSettings(
          userAgent: const WebSetting<String?>.of('Dart Test'),
        ),
      );
      final Map<String, dynamic> creationParamsMap =
          MethodChannelWebViewPlatform.creationParamsToMap(creationParams);

      expect(creationParamsMap['backgroundColor'], whiteColor.value);
    });
  });

  group('Tests on `plugins.flutter.io/cookie_manager` channel', () {
    const MethodChannel cookieChannel =
        MethodChannel('plugins.flutter.io/cookie_manager');

    final List<MethodCall> log = <MethodCall>[];
    cookieChannel.setMockMethodCallHandler((MethodCall methodCall) async {
      log.add(methodCall);

      if (methodCall.method == 'clearCookies') {
        return true;
      }

      // Return null explicitly instead of relying on the implicit null
      // returned by the method channel if no return statement is specified.
      return null;
    });

    tearDown(() {
      log.clear();
    });

    test('clearCookies', () async {
      final bool clearCookies =
          await MethodChannelWebViewPlatform.clearCookies();

      expect(clearCookies, true);
      expect(
        log,
        <Matcher>[
          isMethodCall(
            'clearCookies',
            arguments: null,
          ),
        ],
      );
    });

    test('setCookie', () async {
      await MethodChannelWebViewPlatform.setCookie(const WebViewCookie(
          name: 'foo', value: 'bar', domain: 'flutter.dev'));

      expect(
        log,
        <Matcher>[
          isMethodCall(
            'setCookie',
            arguments: <String, String>{
              'name': 'foo',
              'value': 'bar',
              'domain': 'flutter.dev',
              'path': '/',
            },
          ),
        ],
      );
    });
  });
}

class MockWebViewPlatformCallbacksHandler extends Mock
    implements WebViewPlatformCallbacksHandler {}

class MockJavascriptChannelRegistry extends Mock
    implements JavascriptChannelRegistry {}
