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

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding;

import '../flutter_test_alternative.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('BasicMessageChannel', () {
    const MessageCodec<String> string = StringCodec();
    const BasicMessageChannel<String> channel = BasicMessageChannel<String>('ch', string);
    test('can send string message and get reply', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch',
        (ByteData message) async => string.encodeMessage(string.decodeMessage(message) + ' world'),
      );
      final String reply = await channel.send('hello');
      expect(reply, equals('hello world'));
    });
    test('can receive string message and send reply', () async {
      channel.setMessageHandler((String message) async => message + ' world');
      String reply;
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'ch',
        const StringCodec().encodeMessage('hello'),
        (ByteData replyBinary) {
          reply = string.decodeMessage(replyBinary);
        },
      );
      expect(reply, equals('hello world'));
    });
  });

  group('MethodChannel', () {
    const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
    const MethodCodec jsonMethod = JSONMethodCodec();
    const MethodChannel channel = MethodChannel('ch7', jsonMethod);
    const OptionalMethodChannel optionalMethodChannel = OptionalMethodChannel('ch8', jsonMethod);
    test('can invoke method and get result', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch7',
        (ByteData message) async {
          final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
          if (methodCall['method'] == 'sayHello') {
            return jsonMessage.encodeMessage(<dynamic>['${methodCall['args']} world']);
          } else {
            return jsonMessage.encodeMessage(<dynamic>['unknown', null, null]);
          }
        },
      );
      final String result = await channel.invokeMethod('sayHello', 'hello');
      expect(result, equals('hello world'));
    });
    test('can invoke list method and get result', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch7',
        (ByteData message) async {
          final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
          if (methodCall['method'] == 'sayHello') {
            return jsonMessage.encodeMessage(<dynamic>[<String>['${methodCall['args']}', 'world']]);
          } else {
            return jsonMessage.encodeMessage(<dynamic>['unknown', null, null]);
          }
        },
      );
      expect(channel.invokeMethod<List<String>>('sayHello', 'hello'), throwsA(isA<TypeError>()));
      expect(await channel.invokeListMethod<String>('sayHello', 'hello'), <String>['hello', 'world']);
    });

    test('can invoke list method and get null result', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch7',
        (ByteData message) async {
          final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
          if (methodCall['method'] == 'sayHello') {
            return jsonMessage.encodeMessage(<dynamic>[null]);
          } else {
            return jsonMessage.encodeMessage(<dynamic>['unknown', null, null]);
          }
        },
      );
      expect(await channel.invokeListMethod<String>('sayHello', 'hello'), null);
    });


    test('can invoke map method and get result', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch7',
        (ByteData message) async {
          final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
          if (methodCall['method'] == 'sayHello') {
            return jsonMessage.encodeMessage(<dynamic>[<String, String>{'${methodCall['args']}': 'world'}]);
          } else {
            return jsonMessage.encodeMessage(<dynamic>['unknown', null, null]);
          }
        },
      );
      expect(channel.invokeMethod<Map<String, String>>('sayHello', 'hello'), throwsA(isA<TypeError>()));
      expect(await channel.invokeMapMethod<String, String>('sayHello', 'hello'), <String, String>{'hello': 'world'});
    });

    test('can invoke map method and get null result', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch7',
        (ByteData message) async {
          final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
          if (methodCall['method'] == 'sayHello') {
            return jsonMessage.encodeMessage(<dynamic>[null]);
          } else {
            return jsonMessage.encodeMessage(<dynamic>['unknown', null, null]);
          }
        },
      );
      expect(await channel.invokeMapMethod<String, String>('sayHello', 'hello'), null);
    });

    test('can invoke method and get error', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch7',
        (ByteData message) async {
          return jsonMessage.encodeMessage(<dynamic>[
            'bad',
            'Something happened',
            <String, dynamic>{'a': 42, 'b': 3.14},
          ]);
        },
      );
      try {
        await channel.invokeMethod<dynamic>('sayHello', 'hello');
        fail('Exception expected');
      } on PlatformException catch (e) {
        expect(e.code, equals('bad'));
        expect(e.message, equals('Something happened'));
        expect(e.details, equals(<String, dynamic>{'a': 42, 'b': 3.14}));
      } catch (e) {
        fail('PlatformException expected');
      }
    });
    test('can invoke unimplemented method', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch7',
        (ByteData message) async => null,
      );
      try {
        await channel.invokeMethod<void>('sayHello', 'hello');
        fail('Exception expected');
      } on MissingPluginException catch (e) {
        expect(e.message, contains('sayHello'));
        expect(e.message, contains('ch7'));
      } catch (e) {
        fail('MissingPluginException expected');
      }
    });
    test('can invoke unimplemented method (optional)', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch8',
        (ByteData message) async => null,
      );
      final String result = await optionalMethodChannel.invokeMethod<String>('sayHello', 'hello');
      expect(result, isNull);
    });
    test('can handle method call with no registered plugin', () async {
      channel.setMethodCallHandler(null);
      final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
      ByteData envelope;
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
        envelope = result;
      });
      expect(envelope, isNull);
    });
    test('can handle method call of unimplemented method', () async {
      channel.setMethodCallHandler((MethodCall call) async {
        throw MissingPluginException();
      });
      final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
      ByteData envelope;
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
        envelope = result;
      });
      expect(envelope, isNull);
    });
    test('can handle method call with successful result', () async {
      channel.setMethodCallHandler((MethodCall call) async => '${call.arguments}, world');
      final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
      ByteData envelope;
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
        envelope = result;
      });
      expect(jsonMethod.decodeEnvelope(envelope), equals('hello, world'));
    });
    test('can handle method call with expressive error result', () async {
      channel.setMethodCallHandler((MethodCall call) async {
        throw PlatformException(code: 'bad', message: 'sayHello failed', details: null);
      });
      final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
      ByteData envelope;
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
        envelope = result;
      });
      try {
        jsonMethod.decodeEnvelope(envelope);
        fail('Exception expected');
      } on PlatformException catch (e) {
        expect(e.code, equals('bad'));
        expect(e.message, equals('sayHello failed'));
      } catch (e) {
        fail('PlatformException expected');
      }
    });
    test('can handle method call with other error result', () async {
      channel.setMethodCallHandler((MethodCall call) async {
        throw ArgumentError('bad');
      });
      final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
      ByteData envelope;
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
        envelope = result;
      });
      try {
        jsonMethod.decodeEnvelope(envelope);
        fail('Exception expected');
      } on PlatformException catch (e) {
        expect(e.code, equals('error'));
        expect(e.message, equals('Invalid argument(s): bad'));
      } catch (e) {
        fail('PlatformException expected');
      }
    });
  });
  group('EventChannel', () {
    const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
    const MethodCodec jsonMethod = JSONMethodCodec();
    const EventChannel channel = EventChannel('ch', jsonMethod);
    void emitEvent(ByteData event) {
      ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'ch',
        event,
        (ByteData reply) { },
      );
    }
    test('can receive event stream', () async {
      bool canceled = false;
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch',
        (ByteData message) async {
          final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
          if (methodCall['method'] == 'listen') {
            final String argument = methodCall['args'] as String;
            emitEvent(jsonMethod.encodeSuccessEnvelope(argument + '1'));
            emitEvent(jsonMethod.encodeSuccessEnvelope(argument + '2'));
            emitEvent(null);
            return jsonMethod.encodeSuccessEnvelope(null);
          } else if (methodCall['method'] == 'cancel') {
            canceled = true;
            return jsonMethod.encodeSuccessEnvelope(null);
          } else {
            fail('Expected listen or cancel');
          }
        },
      );
      final List<dynamic> events = await channel.receiveBroadcastStream('hello').toList();
      expect(events, orderedEquals(<String>['hello1', 'hello2']));
      await Future<void>.delayed(Duration.zero);
      expect(canceled, isTrue);
    });
    test('can receive error event', () async {
      ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
        'ch',
        (ByteData message) async {
          final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
          if (methodCall['method'] == 'listen') {
            final String argument = methodCall['args'] as String;
            emitEvent(jsonMethod.encodeErrorEnvelope(code: '404', message: 'Not Found.', details: argument));
            return jsonMethod.encodeSuccessEnvelope(null);
          } else if (methodCall['method'] == 'cancel') {
            return jsonMethod.encodeSuccessEnvelope(null);
          } else {
            fail('Expected listen or cancel');
          }
        },
      );
      final List<dynamic> events = <dynamic>[];
      final List<dynamic> errors = <dynamic>[];
      channel.receiveBroadcastStream('hello').listen(events.add, onError: errors.add);
      await Future<void>.delayed(Duration.zero);
      expect(events, isEmpty);
      expect(errors, hasLength(1));
      expect(errors[0], isA<PlatformException>());
      final PlatformException error = errors[0] as PlatformException;
      expect(error.code, '404');
      expect(error.message, 'Not Found.');
      expect(error.details, 'hello');
    });
  });
}
