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

import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';

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 adddress 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);
  }
}
