// 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/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 '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('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,
          ),
        ],
      );
    });
  });

  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 {}
