// 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)))
      .thenAnswer((_) => 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)))
              .thenAnswer((_) => 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 {}
