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

import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';

void main() {
  group('FuchsiaRemoteConnection.connect', () {
    MockSshCommandRunner mockRunner;

    setUp(() {
      mockRunner = new MockSshCommandRunner();
    });

    tearDown(() {
      /// Most tests will mock out the port forwarding and connection
      /// functions.
      restoreFuchsiaPortForwardingFunction();
      restoreVmServiceConnectionFunction();
    });

    test('end-to-end with three vm connections and flutter view query',
        () async {
      const String address = 'fe80::8eae:4cff:fef4:9247';
      const String interface = 'eno1';
      // Adds some extra junk to make sure the strings will be cleaned up.
      when(mockRunner.run(typed(any)))
      .thenReturn(new Future<List<String>>.value(
          <String>['123\n\n\n', '456  ', '789']));
      when(mockRunner.address).thenReturn(address);
      when(mockRunner.interface).thenReturn(interface);
      int port = 0;
      final List<MockPortForwarder> forwardedPorts = <MockPortForwarder>[];
      Future<PortForwarder> mockPortForwardingFunction(
          String address, int remotePort,
          [String interface = '', String configFile]) {
        return new Future<PortForwarder>(() {
          final MockPortForwarder pf = new MockPortForwarder();
          forwardedPorts.add(pf);
          when(pf.port).thenReturn(port++);
          when(pf.remotePort).thenReturn(remotePort);
          return pf;
        });
      }

      int flutterViewIndex = 0;
      final List<Map<String, dynamic>> flutterViewCannedResponses =
          <Map<String, dynamic>>[
        <String, dynamic>{
          'views': <Map<String, dynamic>>[
            <String, dynamic>{
              'type': 'FlutterView',
              'id': 'flutterView0',
            },
          ],
        },
        <String, dynamic>{
          'views': <Map<String, dynamic>>[
            <String, dynamic>{
              'type': 'FlutterView',
              'id': 'flutterView1',
              'isolate': <String, dynamic>{
                'type': '@Isolate',
                'fixedId': 'true',
                'id': 'isolates/1',
                'name': 'file://flutterBinary1',
                'number': '1',
              },
            }
          ],
        },
        <String, dynamic>{
          'views': <Map<String, dynamic>>[
            <String, dynamic>{
              'type': 'FlutterView',
              'id': 'flutterView2',
              'isolate': <String, dynamic>{
                'type': '@Isolate',
                'fixedId': 'true',
                'id': 'isolates/2',
                'name': 'file://flutterBinary2',
                'number': '2',
              },
            }
          ],
        },
      ];

      final List<MockPeer> mockPeerConnections = <MockPeer>[];
      final List<Uri> uriConnections = <Uri>[];
      Future<json_rpc.Peer> mockVmConnectionFunction(Uri uri) {
        return new Future<json_rpc.Peer>(() async {
          final MockPeer mp = new MockPeer();
          mockPeerConnections.add(mp);
          uriConnections.add(uri);
          when(mp.sendRequest(typed<String>(any), typed<String>(any)))
              .thenReturn(new Future<Map<String, dynamic>>(
                  () => flutterViewCannedResponses[flutterViewIndex++]));
          return mp;
        });
      }

      fuchsiaPortForwardingFunction = mockPortForwardingFunction;
      fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction;

      final FuchsiaRemoteConnection connection =
          await FuchsiaRemoteConnection.connectWithSshCommandRunner(mockRunner);

      // [mockPortForwardingFunction] will have returned three different
      // forwarded ports, incrementing the port each time by one. (Just a sanity
      // check that the forwarding port was called).
      expect(forwardedPorts.length, 3);
      expect(forwardedPorts[0].remotePort, 123);
      expect(forwardedPorts[1].remotePort, 456);
      expect(forwardedPorts[2].remotePort, 789);
      expect(forwardedPorts[0].port, 0);
      expect(forwardedPorts[1].port, 1);
      expect(forwardedPorts[2].port, 2);

      final List<FlutterView> views = await connection.getFlutterViews();
      expect(views, isNot(null));
      expect(views.length, 3);
      // Since name can be null, check for the ID on all of them.
      expect(views[0].id, 'flutterView0');
      expect(views[1].id, 'flutterView1');
      expect(views[2].id, 'flutterView2');

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

      // Ensure the ports are all closed after stop was called.
      await connection.stop();
      verify(forwardedPorts[0].stop());
      verify(forwardedPorts[1].stop());
      verify(forwardedPorts[2].stop());
    });
  });
}

class MockSshCommandRunner extends Mock implements SshCommandRunner {}

class MockPortForwarder extends Mock implements PortForwarder {}

class MockPeer extends Mock implements json_rpc.Peer {}
