// 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 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vms;

import 'common.dart';

void main() {
  group('FuchsiaRemoteConnection.connect', () {
    late List<FakePortForwarder> forwardedPorts;
    List<FakeVmService> fakeVmServices;
    late List<Uri> uriConnections;

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

      forwardedPorts = <FakePortForwarder>[];
      fakeVmServices = <FakeVmService>[];
      uriConnections = <Uri>[];
      Future<vms.VmService> fakeVmConnectionFunction(
        Uri uri, {
        Duration? timeout,
      }) {
        return Future<vms.VmService>(() async {
          final FakeVmService service = FakeVmService();
          fakeVmServices.add(service);
          uriConnections.add(uri);
          service.flutterListViews = vms.Response.parse(flutterViewCannedResponses[uri.port]);
          return service;
        });
      }

      fuchsiaVmServiceConnectionFunction = fakeVmConnectionFunction;
    });

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

    test('end-to-end with three vm connections and flutter view query', () async {
      int port = 0;
      Future<PortForwarder> fakePortForwardingFunction(
        String address,
        int remotePort, [
        String? interface = '',
        String? configFile,
      ]) {
        return Future<PortForwarder>(() {
          final FakePortForwarder pf = FakePortForwarder();
          forwardedPorts.add(pf);
          pf.port = port++;
          pf.remotePort = remotePort;
          return pf;
        });
      }

      fuchsiaPortForwardingFunction = fakePortForwardingFunction;
      final FakeSshCommandRunner fakeRunner = FakeSshCommandRunner();
      // Adds some extra junk to make sure the strings will be cleaned up.
      fakeRunner.findResponse = <String>['/hub/blah/blah/blah/vmservice-port\n'];
      fakeRunner.lsResponse = <String>['123\n\n\n', '456  ', '789'];
      fakeRunner.address = 'fe80::8eae:4cff:fef4:9247';
      fakeRunner.interface = 'eno1';

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

      // [fakePortForwardingFunction] 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);

      // VMs should be accessed via localhost ports given by
      // [fakePortForwardingFunction].
      expect(uriConnections[0],
        Uri(scheme:'ws', host:'[::1]', port:0, path:'/ws'));
      expect(uriConnections[1],
        Uri(scheme:'ws', host:'[::1]', port:1, path:'/ws'));
      expect(uriConnections[2],
        Uri(scheme:'ws', host:'[::1]', port:2, path:'/ws'));

      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();
      expect(forwardedPorts[0].stopped, true);
      expect(forwardedPorts[1].stopped, true);
      expect(forwardedPorts[2].stopped, true);
    });

    test('end-to-end with three vms and remote open port', () async {
      int port = 0;
      Future<PortForwarder> fakePortForwardingFunction(
        String address,
        int remotePort, [
        String? interface = '',
        String? configFile,
      ]) {
        return Future<PortForwarder>(() {
          final FakePortForwarder pf = FakePortForwarder();
          forwardedPorts.add(pf);
          pf.port = port++;
          pf.remotePort = remotePort;
          pf.openPortAddress = 'fe80::1:2%eno2';
          return pf;
        });
      }

      fuchsiaPortForwardingFunction = fakePortForwardingFunction;
      final FakeSshCommandRunner fakeRunner = FakeSshCommandRunner();
      // Adds some extra junk to make sure the strings will be cleaned up.
      fakeRunner.findResponse = <String>['/hub/blah/blah/blah/vmservice-port\n'];
      fakeRunner.lsResponse = <String>['123\n\n\n', '456  ', '789'];
      fakeRunner.address = 'fe80::8eae:4cff:fef4:9247';
      fakeRunner.interface = 'eno1';
      final FuchsiaRemoteConnection connection =
          await FuchsiaRemoteConnection.connectWithSshCommandRunner(fakeRunner);

      // [fakePortForwardingFunction] 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);

      // VMs should be accessed via the alternate address given by
      // [fakePortForwardingFunction].
      expect(uriConnections[0],
        Uri(scheme:'ws', host:'[fe80::1:2%25eno2]', port:0, path:'/ws'));
      expect(uriConnections[1],
        Uri(scheme:'ws', host:'[fe80::1:2%25eno2]', port:1, path:'/ws'));
      expect(uriConnections[2],
        Uri(scheme:'ws', host:'[fe80::1:2%25eno2]', port:2, path:'/ws'));

      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();
      expect(forwardedPorts[0].stopped, true);
      expect(forwardedPorts[1].stopped, true);
      expect(forwardedPorts[2].stopped, true);
    });

    test('end-to-end with three vms and ipv4', () async {
      int port = 0;
      Future<PortForwarder> fakePortForwardingFunction(
        String address,
        int remotePort, [
        String? interface = '',
        String? configFile,
      ]) {
        return Future<PortForwarder>(() {
          final FakePortForwarder pf = FakePortForwarder();
          forwardedPorts.add(pf);
          pf.port = port++;
          pf.remotePort = remotePort;
          return pf;
        });
      }

      fuchsiaPortForwardingFunction = fakePortForwardingFunction;
      final FakeSshCommandRunner fakeRunner = FakeSshCommandRunner();
      // Adds some extra junk to make sure the strings will be cleaned up.
      fakeRunner.findResponse = <String>['/hub/blah/blah/blah/vmservice-port\n'];
      fakeRunner.lsResponse = <String>['123\n\n\n', '456  ', '789'];
      fakeRunner.address = '196.168.1.4';

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

      // [fakePortForwardingFunction] 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);

      // VMs should be accessed via the ipv4 loopback.
      expect(uriConnections[0],
        Uri(scheme:'ws', host:'127.0.0.1', port:0, path:'/ws'));
      expect(uriConnections[1],
        Uri(scheme:'ws', host:'127.0.0.1', port:1, path:'/ws'));
      expect(uriConnections[2],
        Uri(scheme:'ws', host:'127.0.0.1', port:2, path:'/ws'));

      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();
      expect(forwardedPorts[0].stopped, true);
      expect(forwardedPorts[1].stopped, true);
      expect(forwardedPorts[2].stopped, true);
    });

    test('env variable test without remote addr', () async {
      Future<void> failingFunction() async {
        await FuchsiaRemoteConnection.connect();
      }

      // Should fail as no env variable has been passed.
      expect(failingFunction,
          throwsA(isA<FuchsiaRemoteConnectionError>()));
    });
  });
}

class FakeSshCommandRunner extends Fake implements SshCommandRunner {
  List<String>? findResponse;
  List<String>? lsResponse;
  @override
  Future<List<String>> run(String command) async {
    if (command.startsWith('/bin/find')) {
      return findResponse!;
    }
    if (command.startsWith('/bin/ls')) {
      return lsResponse!;
    }
    throw UnimplementedError(command);
  }

  @override
  String interface = '';

  @override
  String address = '';

  @override
  String get sshConfigPath => '~/.ssh';
}

class FakePortForwarder extends Fake implements PortForwarder {
  @override
  int port = 0;

  @override
  int remotePort = 0;

  @override
  String? openPortAddress;

  bool stopped = false;
  @override
  Future<void> stop() async {
    stopped = true;
  }
}

class FakeVmService extends Fake implements vms.VmService {
  bool disposed = false;
  vms.Response? flutterListViews;

  @override
  Future<void> dispose() async {
    disposed = true;
  }

  @override
  Future<vms.Response> callMethod(String method, {String? isolateId, Map<String, dynamic>? args}) async {
    if (method == '_flutter.listViews') {
      return flutterListViews!;
    }
    throw UnimplementedError(method);
  }

  @override
  Future<void> onDone = Future<void>.value();

  @override
  Future<vms.Version> getVersion() async {
    return vms.Version(major: -1, minor: -1);
  }
}
