// Copyright 2018 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 'package:fuchsia_remote_debug_protocol/src/dart/dart_vm.dart';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

void main() {
  group('DartVm.connect', () {
    tearDown(() {
      restoreVmServiceConnectionFunction();
    });

    test('null connector', () async {
      Future<json_rpc.Peer> mockServiceFunction(Uri uri) {
        return new Future<json_rpc.Peer>(() => null);
      }

      fuchsiaVmServiceConnectionFunction = mockServiceFunction;
      expect(await DartVm.connect(Uri.parse('http://this.whatever/ws')),
          equals(null));
    });

    test('disconnect closes peer', () async {
      final MockPeer peer = new MockPeer();
      Future<json_rpc.Peer> mockServiceFunction(Uri uri) {
        return new Future<json_rpc.Peer>(() => peer);
      }

      fuchsiaVmServiceConnectionFunction = mockServiceFunction;
      final DartVm vm =
          await DartVm.connect(Uri.parse('http://this.whatever/ws'));
      expect(vm, isNot(null));
      await vm.stop();
      verify(peer.close());
    });
  });

  group('DartVm.getAllFlutterViews', () {
    MockPeer mockPeer;

    setUp(() {
      mockPeer = new MockPeer();
    });

    tearDown(() {
      restoreVmServiceConnectionFunction();
    });

    test('basic flutter view parsing', () async {
      final Map<String, dynamic> flutterViewCannedResponses = <String, dynamic>{
        'views': <Map<String, dynamic>>[
          <String, dynamic>{
            'type': 'FlutterView',
            'id': 'flutterView0',
          },
          <String, dynamic>{
            'type': 'FlutterView',
            'id': 'flutterView1',
            'isolate': <String, dynamic>{
              'type': '@Isolate',
              'fixedId': 'true',
              'id': 'isolates/1',
              'name': 'file://flutterBinary1',
              'number': '1',
            },
          },
          <String, dynamic>{
            'type': 'FlutterView',
            'id': 'flutterView2',
            'isolate': <String, dynamic>{
              'type': '@Isolate',
              'fixedId': 'true',
              'id': 'isolates/2',
              'name': 'file://flutterBinary2',
              'number': '2',
            },
          },
        ],
      };

      Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) {
        when(mockPeer.sendRequest(
                typed<String>(any), typed<Map<String, dynamic>>(any)))
            .thenReturn(new Future<Map<String, dynamic>>(
                () => flutterViewCannedResponses));
        return new Future<json_rpc.Peer>(() => mockPeer);
      }

      fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction;
      final DartVm vm =
          await DartVm.connect(Uri.parse('http://whatever.com/ws'));
      expect(vm, isNot(null));
      final List<FlutterView> views = await vm.getAllFlutterViews();
      expect(views.length, 3);
      // Check ID's as they cannot be null.
      expect(views[0].id, 'flutterView0');
      expect(views[1].id, 'flutterView1');
      expect(views[2].id, 'flutterView2');

      // Verify names.
      expect(views[0].name, equals(null));
      expect(views[1].name, 'file://flutterBinary1');
      expect(views[2].name, 'file://flutterBinary2');
    });

    test('invalid flutter view missing ID', () async {
      final Map<String, dynamic> flutterViewCannedResponseMissingId =
          <String, dynamic>{
        'views': <Map<String, dynamic>>[
          // Valid flutter view.
          <String, dynamic>{
            'type': 'FlutterView',
            'id': 'flutterView1',
            'isolate': <String, dynamic>{
              'type': '@Isolate',
              'name': 'IsolateThing',
              'fixedId': 'true',
              'id': 'isolates/1',
              'number': '1',
            },
          },

          // Missing ID.
          <String, dynamic>{
            'type': 'FlutterView',
          },
        ]
      };

      Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) {
        when(mockPeer.sendRequest(
                typed<String>(any), typed<Map<String, dynamic>>(any)))
            .thenReturn(new Future<Map<String, dynamic>>(
                () => flutterViewCannedResponseMissingId));
        return new Future<json_rpc.Peer>(() => mockPeer);
      }

      fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction;
      final DartVm vm =
          await DartVm.connect(Uri.parse('http://whatever.com/ws'));
      expect(vm, isNot(null));
      Future<Null> failingFunction() async {
        await vm.getAllFlutterViews();
      }

      // Both views should be invalid as they were missing required fields.
      expect(failingFunction, throwsA(const isInstanceOf<RpcFormatError>()));
    });

    test('invalid flutter view missing ID', () async {
      final Map<String, dynamic> flutterViewCannedResponseMissingIsolateName =
          <String, dynamic>{
        'views': <Map<String, dynamic>>[
          // Missing isolate name.
          <String, dynamic>{
            'type': 'FlutterView',
            'id': 'flutterView1',
            'isolate': <String, dynamic>{
              'type': '@Isolate',
              'fixedId': 'true',
              'id': 'isolates/1',
              'number': '1',
            },
          },
        ],
      };

      Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) {
        when(mockPeer.sendRequest(
                typed<String>(any), typed<Map<String, dynamic>>(any)))
            .thenReturn(new Future<Map<String, dynamic>>(
                () => flutterViewCannedResponseMissingIsolateName));
        return new Future<json_rpc.Peer>(() => mockPeer);
      }

      fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction;
      final DartVm vm =
          await DartVm.connect(Uri.parse('http://whatever.com/ws'));
      expect(vm, isNot(null));
      Future<Null> failingFunction() async {
        await vm.getAllFlutterViews();
      }

      // Both views should be invalid as they were missing required fields.
      expect(failingFunction, throwsA(const isInstanceOf<RpcFormatError>()));
    });
  });

  group('DartVm.invokeRpc', () {
    MockPeer mockPeer;

    setUp(() {
      mockPeer = new MockPeer();
    });

    tearDown(() {
      restoreVmServiceConnectionFunction();
    });

    test('verify timeout fires', () async {
      const Duration timeoutTime = const Duration(milliseconds: 100);
      Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) {
        // Return a command that will never complete.
        when(mockPeer.sendRequest(
                typed<String>(any), typed<Map<String, dynamic>>(any)))
            .thenReturn(new Completer<Map<String, dynamic>>().future);
        return new Future<json_rpc.Peer>(() => mockPeer);
      }

      fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction;
      final DartVm vm =
          await DartVm.connect(Uri.parse('http://whatever.com/ws'));
      expect(vm, isNot(null));
      Future<Null> failingFunction() async {
        await vm.invokeRpc('somesillyfunction', timeout: timeoutTime);
      }

      expect(failingFunction, throwsA(const isInstanceOf<TimeoutException>()));
    });
  });
}

class MockPeer extends Mock implements json_rpc.Peer {}
