// Copyright 2013 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.

library observatory_sky_shell_service_client;

import 'dart:async';
import 'dart:convert';
import 'dart:io';

class ServiceClient {
  Completer<dynamic>? isolateStartedId;
  Completer<dynamic>? isolatePausedId;
  Completer<dynamic>? isolateResumeId;

  ServiceClient(
    this.client, {
    this.isolateStartedId,
    this.isolatePausedId,
    this.isolateResumeId,
  }) {
    client.listen(_onData, onError: _onError, cancelOnError: true);
  }

  Future<Map<String, dynamic>> invokeRPC(String method,
      [Map<String, dynamic>? params]) async {
    final String key = _createKey();
    final String request = json.encode(<String, dynamic>{
      'jsonrpc': '2.0',
      'method': method,
      'params': params == null ? <String, dynamic>{} : params,
      'id': key,
    });
    client.add(request);
    final Completer<Map<String, dynamic>> completer =
        Completer<Map<String, dynamic>>();
    _outstandingRequests[key] = completer;
    print('-> $key ($method)');
    return completer.future;
  }

  String _createKey() {
    final String key = '$_id';
    _id++;
    return key;
  }

  void _onData(dynamic message) {
    final Map<String, dynamic> response =
        json.decode(message as String) as Map<String, dynamic>;
    final dynamic key = response['id'];
    if (key != null) {
      print('<- $key');
      final dynamic completer = _outstandingRequests.remove(key);
      assert(completer != null);
      final dynamic result = response['result'];
      final dynamic error = response['error'];
      if (error != null) {
        assert(result == null);
        completer.completeError(error);
      } else {
        assert(result != null);
        completer.complete(result);
      }
    } else {
      if (response['method'] == 'streamNotify') {
        _onServiceEvent(response['params'] as Map<String, dynamic>?);
      }
    }
  }

  void _onServiceEvent(Map<String, dynamic>? params) {
    if (params == null) {
      return;
    }
    final Map<String, dynamic>? event =
        params['event'] as Map<String, dynamic>?;
    if (event == null || event['type'] != 'Event') {
      return;
    }
    final dynamic isolateId = event['isolate']['id'];
    switch (params['streamId']) {
      case 'Isolate':
        if (event['kind'] == 'IsolateStart') {
          isolateStartedId?.complete(isolateId);
        }
        break;
      case 'Debug':
        switch (event['kind']) {
          case 'Resume':
            isolateResumeId?.complete(isolateId);
            break;
          case 'PauseStart':
            isolatePausedId?.complete(isolateId);
            break;
        }
        break;
    }
  }

  void _onError(dynamic error) {
    print('WebSocket error: $error');
  }

  final WebSocket client;
  final Map<String, Completer<dynamic>> _outstandingRequests =
      <String, Completer<dynamic>>{};
  int _id = 1;
}
