// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// @dart = 2.10

@TestOn('vm')
import 'dart:async';
import 'dart:convert';

import 'package:async/async.dart';
import 'package:mockito/mockito.dart';
import 'package:pedantic/pedantic.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';

void main() {
  MockVmService serviceMock;
  StreamController<Map<String, Object>> requestsController;
  StreamController<Map<String, Object>> responsesController;
  ServiceExtensionRegistry serviceRegistry;

  setUp(() {
    serviceMock = MockVmService();
    requestsController = StreamController<Map<String, Object>>();
    responsesController = StreamController<Map<String, Object>>();
    serviceRegistry = ServiceExtensionRegistry();
    VmServerConnection(requestsController.stream, responsesController.sink,
        serviceRegistry, serviceMock);
  });

  tearDown(() {
    requestsController.close();
    responsesController.close();
  });

  group('method delegation', () {
    test('works for simple methods', () {
      var request = rpcRequest("getVersion");
      var version = Version(major: 1, minor: 0);
      when(serviceMock.getVersion()).thenAnswer((_) => Future.value(version));
      expect(responsesController.stream, emits(rpcResponse(version)));
      requestsController.add(request);
    });

    test('works for methods with parameters', () {
      var isolate = Isolate(
        name: 'isolate',
        exceptionPauseMode: ExceptionPauseMode.kNone,
        id: '123',
        number: '0',
        startTime: 1,
        runnable: true,
        livePorts: 2,
        isolateFlags: [],
        pauseOnExit: false,
        pauseEvent: Event(
          kind: EventKind.kResume,
          timestamp: 3,
        ),
        libraries: [],
        breakpoints: [],
        isSystemIsolate: false,
      );
      var request = rpcRequest("getIsolate", params: {'isolateId': isolate.id});
      when(serviceMock.getIsolate(isolate.id))
          .thenAnswer((Invocation invocation) {
        expect(invocation.positionalArguments, equals([isolate.id]));
        return Future.value(isolate);
      });
      expect(responsesController.stream, emits(rpcResponse(isolate)));
      requestsController.add(request);
    });

    test('works for methods with list parameters', () {
      var isolate = Isolate(
        name: 'isolate',
        exceptionPauseMode: ExceptionPauseMode.kNone,
        id: '123',
        number: '0',
        startTime: 1,
        runnable: true,
        livePorts: 2,
        isolateFlags: [],
        pauseOnExit: false,
        pauseEvent: Event(
          kind: EventKind.kResume,
          timestamp: 3,
        ),
        libraries: [],
        breakpoints: [],
        isSystemIsolate: false,
      );
      var request = rpcRequest("setVMTimelineFlags", params: {
        'isolateId': isolate.id,
        // Note: the dynamic list below is intentional in order to exercise the
        // code under test.
        'recordedStreams': <dynamic>['GC', 'Dart', 'Embedder'],
      });
      var response = Success();
      when(serviceMock.getIsolate(isolate.id))
          .thenAnswer((Invocation invocation) {
        expect(invocation.namedArguments,
            equals({Symbol('isolateId'): null, Symbol('args'): null}));
        return Future.value(isolate);
      });
      expect(responsesController.stream, emits(rpcResponse(response)));
      requestsController.add(request);
    });

    group('custom service extensions', () {
      test('with no params or isolateId', () {
        var extension = 'ext.cool';
        var request = rpcRequest(extension, params: null);
        var response = Response()..json = {"hello": "world"};
        when(serviceMock.callServiceExtension(
          extension,
          isolateId: argThat(isNull, named: 'isolateId'),
          args: argThat(isNull, named: 'args'),
        )).thenAnswer((Invocation invocation) {
          expect(invocation.namedArguments,
              equals({Symbol('isolateId'): null, Symbol('args'): null}));
          return Future.value(response);
        });
        expect(responsesController.stream, emits(rpcResponse(response)));
        requestsController.add(request);
      });

      test('with isolateId and no other params', () {
        var extension = 'ext.cool';
        var request = rpcRequest(extension, params: {'isolateId': '1'});
        var response = Response()..json = {"hello": "world"};
        when(serviceMock.callServiceExtension(
          extension,
          isolateId: argThat(equals('1'), named: 'isolateId'),
          args: argThat(equals({}), named: 'args'),
        )).thenAnswer((Invocation invocation) {
          expect(invocation.namedArguments,
              equals({Symbol('isolateId'): '1', Symbol('args'): {}}));
          return Future.value(response);
        });
        expect(responsesController.stream, emits(rpcResponse(response)));
        requestsController.add(request);
      });

      test('with params and no isolateId', () {
        var extension = 'ext.cool';
        var params = {'cool': 'option'};
        var request = rpcRequest(extension, params: params);
        var response = Response()..json = {"hello": "world"};
        when(serviceMock.callServiceExtension(
          extension,
          isolateId: argThat(isNull, named: 'isolateId'),
          args: argThat(equals(params), named: 'args'),
        )).thenAnswer((Invocation invocation) {
          expect(invocation.namedArguments,
              equals({Symbol('isolateId'): null, Symbol('args'): params}));
          return Future.value(response);
        });
        expect(responsesController.stream, emits(rpcResponse(response)));
        requestsController.add(request);
      });

      test('with params and isolateId', () {
        var extension = 'ext.cool';
        var params = {'cool': 'option'};
        var request =
            rpcRequest(extension, params: Map.of(params)..['isolateId'] = '1');
        var response = Response()..json = {"hello": "world"};
        when(serviceMock.callServiceExtension(
          extension,
          isolateId: argThat(equals("1"), named: 'isolateId'),
          args: argThat(equals(params), named: 'args'),
        )).thenAnswer((Invocation invocation) {
          expect(invocation.namedArguments,
              equals({Symbol('isolateId'): '1', Symbol('args'): params}));
          return Future.value(response);
        });
        expect(responsesController.stream, emits(rpcResponse(response)));
        requestsController.add(request);
      });
    });
  });

  group('error handling', () {
    test('special cases RPCError instances', () {
      var request = rpcRequest("getVersion");
      var error =
          RPCError('getVersion', 1234, 'custom message', {'custom': 'data'});
      when(serviceMock.getVersion()).thenAnswer((_) => Future.error(error));
      expect(responsesController.stream, emits(rpcErrorResponse(error)));
      requestsController.add(request);
    });

    test('has a fallback for generic exceptions', () {
      var request = rpcRequest("getVersion");
      var error = UnimplementedError();
      when(serviceMock.getVersion()).thenAnswer((_) => Future.error(error));
      expect(
          responsesController.stream.map((response) => '$response'),
          emits(startsWith(
              '{jsonrpc: 2.0, id: 1, error: {code: -32603, message: getVersion: UnimplementedError')));
      requestsController.add(request);
    });
  });

  group('streams', () {
    test('can be listened to and canceled', () async {
      var streamId = 'Isolate';
      var responseQueue = StreamQueue(responsesController.stream);
      StreamController<Event> eventController;
      {
        var request =
            rpcRequest('streamListen', params: {'streamId': streamId});
        var response = Success();
        when(serviceMock.streamListen(streamId))
            .thenAnswer((_) => Future.value(response));
        requestsController.add(request);
        await expectLater(responseQueue, emitsThrough(rpcResponse(response)));

        eventController = serviceMock.streamControllers[streamId];

        var events = [
          Event(
            kind: EventKind.kIsolateStart,
            timestamp: 0,
          ),
          Event(
            kind: EventKind.kIsolateExit,
            timestamp: 1,
          )
        ];
        events.forEach(eventController.add);
        await expectLater(
            responseQueue,
            emitsInOrder(
                events.map((event) => streamNotifyResponse(streamId, event))));
      }
      {
        var request =
            rpcRequest('streamCancel', params: {'streamId': streamId});
        var response = Success();
        when(serviceMock.streamListen(streamId))
            .thenAnswer((_) => Future.value(response));
        requestsController.add(request);
        await expectLater(responseQueue, emitsThrough(rpcResponse(response)));

        var nextEvent = Event(
          kind: EventKind.kIsolateReload,
          timestamp: 2,
        );
        eventController.add(nextEvent);
        expect(responseQueue,
            neverEmits(streamNotifyResponse(streamId, nextEvent)));

        await pumpEventQueue();
        await eventController.close();
        await responsesController.close();
      }
    });
    test("can't be listened to twice", () {
      var streamId = 'Isolate';
      var responseQueue = StreamQueue(responsesController.stream);
      {
        var request =
            rpcRequest('streamListen', params: {'streamId': streamId});
        var response = Success();
        when(serviceMock.streamListen(streamId))
            .thenAnswer((_) => Future.value(response));
        requestsController.add(request);
        expect(responseQueue, emitsThrough(rpcResponse(response)));
      }
      {
        var request =
            rpcRequest('streamListen', params: {'streamId': streamId});
        var response = Success();
        when(serviceMock.streamListen(streamId))
            .thenAnswer((_) => Future.value(response));
        requestsController.add(request);
        expect(
            responseQueue,
            emitsThrough(rpcErrorResponse(
                RPCError('streamSubcribe', 103, 'Stream already subscribed', {
              'details': "The stream '$streamId' is already subscribed",
            }))));
      }
    });

    test("can't cancel a stream that isn't being listened to", () {
      var streamId = 'Isolate';
      var responseQueue = StreamQueue(responsesController.stream);

      var request = rpcRequest('streamCancel', params: {'streamId': streamId});
      var response = Success();
      when(serviceMock.streamListen(streamId))
          .thenAnswer((_) => Future.value(response));
      requestsController.add(request);
      expect(
          responseQueue,
          emitsThrough(rpcErrorResponse(
              RPCError('streamCancel', 104, 'Stream not subscribed', {
            'details': "The stream '$streamId' is not subscribed",
          }))));
    });

    group('Service', () {
      final serviceStream = 'Service';

      test('gives register and unregister events', () async {
        var serviceId = 'ext.test.service';
        var serviceRegisteredEvent = streamNotifyResponse(
          serviceStream,
          Event(
            kind: EventKind.kServiceRegistered,
            timestamp: 0,
            method: serviceId,
            service: serviceId,
          ),
        );
        var serviceUnRegisteredEvent = streamNotifyResponse(
          serviceStream,
          Event(
            kind: EventKind.kServiceUnregistered,
            timestamp: 0,
            method: serviceId,
            service: serviceId,
          ),
        );

        requestsController.add(
            rpcRequest('streamListen', params: {'streamId': serviceStream}));
        requestsController
            .add(rpcRequest('registerService', params: {'service': serviceId}));
        await expectLater(
            responsesController.stream
                .map((Map response) => stripEventTimestamp(response)),
            emitsThrough(serviceRegisteredEvent));

        // Connect another client to get the previous register events and the
        // unregister event.
        var requestsController2 = StreamController<Map<String, Object>>();
        var responsesController2 = StreamController<Map<String, Object>>();
        addTearDown(() {
          requestsController2.close();
          responsesController2.close();
        });

        VmServerConnection(
          requestsController2.stream,
          responsesController2.sink,
          serviceRegistry,
          VmService(Stream.empty(), (String _) => null),
        );

        expect(
            responsesController2.stream
                .map((Map response) => stripEventTimestamp(response)),
            emitsThrough(emitsInOrder(
                [serviceRegisteredEvent, serviceUnRegisteredEvent])));

        // Should get the previously registered extension event, as well as
        // the unregister event when the client disconnects.
        requestsController2.add(
            rpcRequest('streamListen', params: {'streamId': serviceStream}));
        // Need to give the client a chance to subscribe.
        await pumpEventQueue();
        unawaited(requestsController.close());
        // Give the old client a chance to shut down
        await pumpEventQueue();

        // Connect yet another client, it should get zero registration or
        // unregistration events.
        var requestsController3 = StreamController<Map<String, Object>>();
        var responsesController3 = StreamController<Map<String, Object>>();

        VmServerConnection(
          requestsController3.stream,
          responsesController3.sink,
          serviceRegistry,
          VmService(Stream.empty(), (String _) => null),
        );
        expect(
            responsesController3.stream,
            neverEmits(
                anyOf(serviceRegisteredEvent, serviceUnRegisteredEvent)));
        // Give it a chance to deliver events.
        await pumpEventQueue();
        // Disconnect the client so the test can shut down.
        unawaited(requestsController3.close());
        unawaited(responsesController3.close());
      });
    });
  });

  group('registerService', () {
    test('can delegate requests between clients', () async {
      var serviceId = 'ext.test.service';
      var responseQueue = StreamQueue(responsesController.stream);

      var clientInputController =
          StreamController<Map<String, Object>>.broadcast();
      var clientOutputController =
          StreamController<Map<String, Object>>.broadcast();
      var client = VmService(clientInputController.stream.map(jsonEncode),
          (String message) => clientOutputController.add(jsonDecode(message)),
          disposeHandler: () async {
        await clientInputController.close();
        await clientOutputController.close();
      });

      var clientConnection = VmServerConnection(clientOutputController.stream,
          clientInputController.sink, serviceRegistry, serviceMock);

      var requestParams = {'foo': 'bar'};
      var expectedResponse = Response()..json = {'zap': 'zip'};
      await client.registerService(serviceId, 'service');
      // Duplicate registrations should fail.
      expect(client.registerService(serviceId, 'service'),
          throwsA(const TypeMatcher<RPCError>()));

      client.registerServiceCallback(serviceId, (request) async {
        expect(request, equals(requestParams));
        return {'result': expectedResponse.toJson()};
      });

      var serviceRequest = rpcRequest(serviceId, params: requestParams);

      requestsController.add(serviceRequest);
      expect(await responseQueue.next, rpcResponse(expectedResponse));

      // Kill the client that registered the handler, it should now fall back
      // on `callServiceExtension`.
      await client.dispose();
      // This should complete as well.
      await clientConnection.done;

      var mockResponse = Response()..json = {'mock': 'response'};
      when(serviceMock.callServiceExtension(serviceId,
              args: argThat(equals(requestParams), named: 'args'),
              isolateId: argThat(isNull, named: 'isolateId')))
          .thenAnswer((_) async => mockResponse);

      requestsController.add(serviceRequest);
      expect(await responseQueue.next, rpcResponse(mockResponse));
    });
  });
}

Map<String, Object> rpcRequest(String method,
        {Map<String, Object> params = const {}, String id = "1"}) =>
    {
      "jsonrpc": "2.0",
      "method": method,
      "params": params,
      "id": id,
    };

Map<String, Object> rpcResponse(Response response, {String id = "1"}) => {
      'jsonrpc': '2.0',
      'id': id,
      'result': response.toJson(),
    };

Map<String, Object> rpcErrorResponse(Object error, {String id = "1"}) {
  Map<String, Object> errorJson;
  if (error is RPCError) {
    errorJson = {
      'code': error.code,
      'message': error.message,
    };
    if (error.data != null) {
      errorJson['data'] = error.data;
    }
  } else {
    errorJson = {
      'code': -32603,
      'message': error.toString(),
    };
  }
  return {
    'jsonrpc': '2.0',
    'id': id,
    'error': errorJson,
  };
}

Map<String, Object> streamNotifyResponse(String streamId, Event event) {
  return {
    'jsonrpc': '2.0',
    'method': 'streamNotify',
    'params': {
      'streamId': '$streamId',
      'event': event.toJson(),
    },
  };
}

Map<String, Object> stripEventTimestamp(Map response) {
  if (response.containsKey('params') &&
      response['params'].containsKey('event')) {
    response['params']['event']['timestamp'] = 0;
  }
  return response as Map<String, Object>;
}

class MockVmService extends Mock implements VmServiceInterface {
  final streamControllers = <String, StreamController<Event>>{};

  @override
  Stream<Event> onEvent(String streamId) => streamControllers
      .putIfAbsent(streamId, () => StreamController<Event>())
      .stream;

  @override
  Future<Success> setVMTimelineFlags(List<String> recordedStreams) async {
    return Success();
  }
}
