// 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);
    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']);
      }
    }
  }

  void _onServiceEvent(Map<String, dynamic> params) {
    if (params == null) {
      return;
    }
    final Map<String, dynamic> event = params['event'];
    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;
}
