// Copyright (c) 2015, 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.

/// Support for interacting with an analysis server that is running in a
/// separate process.
import 'dart:async';
import 'dart:collection';
import 'dart:convert' hide JsonDecoder;
import 'dart:io';
import 'dart:math' as math;

import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:path/path.dart' as path;

import 'logger.dart';

/// Return the current time expressed as milliseconds since the epoch.
int get currentTime => DateTime.now().millisecondsSinceEpoch;

/// ???
class ErrorMap {
  /// A table mapping file paths to the errors associated with that file.
  final Map<String, List<AnalysisError>> pathMap =
      HashMap<String, List<AnalysisError>>();

  /// Initialize a newly created error map.
  ErrorMap();

  /// Initialize a newly created error map to contain the same mapping as the
  /// given [errorMap].
  ErrorMap.from(ErrorMap errorMap) {
    pathMap.addAll(errorMap.pathMap);
  }

  void operator []=(String filePath, List<AnalysisError> errors) {
    pathMap[filePath] = errors;
  }
}

/// Data that has been collected about a request sent to the server.
class RequestData {
  /// The unique id of the request.
  final String id;

  /// The method that was requested.
  final String method;

  /// The request parameters, or `null` if there are no parameters.
  final Map<String, dynamic>? params;

  /// The time at which the request was sent.
  final int requestTime;

  /// The time at which the response was received, or `null` if no response has
  /// been received.
  int? responseTime;

  /// The response that was received.
  Response? _response;

  /// The completer that will be completed when a response is received.
  Completer<Response>? _responseCompleter;

  /// Initialize a newly created set of request data.
  RequestData(this.id, this.method, this.params, this.requestTime);

  /// Return the number of milliseconds that elapsed between the request and the
  /// response. This getter assumes that the response was received.
  int get elapsedTime => responseTime! - requestTime;

  /// Return a future that will complete when a response is received.
  Future<Response> get respondedTo {
    if (_response != null) {
      return Future.value(_response);
    }
    var completer = _responseCompleter ??= Completer<Response>();
    return completer.future;
  }

  /// Record that the given [response] was received.
  void recordResponse(Response response) {
    if (_response != null) {
      stdout.writeln(
          'Received a second response to a $method request (id = $id)');
      return;
    }
    responseTime = currentTime;
    _response = response;
    var completer = _responseCompleter;
    if (completer != null) {
      completer.complete(response);
      _responseCompleter = null;
    }
  }
}

/// A utility for starting and communicating with an analysis server that is
/// running in a separate process.
class Server {
  /// The label used for communications from the client.
  static const String fromClient = 'client';

  /// The label used for normal communications from the server.
  static const String fromServer = 'server';

  /// The label used for output written by the server on [fromStderr].
  static const String fromStderr = 'stderr';

  /// The logger to which the communications log should be written, or `null` if
  /// the log should not be written.
  final Logger? logger;

  /// The process in which the server is running, or `null` if the server hasn't
  /// been started yet.
  Process? _process;

  /// Number that should be used to compute the 'id' to send in the next command
  /// sent to the server.
  int _nextId = 0;

  /// The analysis roots that are included.
  List<String> _analysisRootIncludes = <String>[];

  /// A list containing the paths of files for which an overlay has been
  /// created.
  List<String> filesWithOverlays = <String>[];

  /// The files that the server reported as being analyzed.
  List<String> _analyzedFiles = <String>[];

  /// A mapping from the absolute paths of files to the most recent set of
  /// errors received for that file.
  final ErrorMap _errorMap = ErrorMap();

  /// The completer that will be completed the next time a 'server.status'
  /// notification is received from the server with 'analyzing' set to false.
  Completer<void>? _analysisFinishedCompleter;

  /// The completer that will be completed the next time a 'server.connected'
  /// notification is received from the server.
  Completer<void>? _serverConnectedCompleter;

  /// A table mapping the ids of requests that have been sent to the server to
  /// data about those requests.
  final Map<String, RequestData> _requestDataMap = <String, RequestData>{};

  /// A table mapping the number of times a request whose 'event' is equal to
  /// the key was sent to the server.
  final Map<String, int> _notificationCountMap = <String, int>{};

  /// Initialize a new analysis server. The analysis server is not running and
  /// must be started using [start].
  ///
  /// If a [logger] is provided, the communications between the client (this
  /// test) and the server will be written to it.
  Server({this.logger});

  /// Return a future that will complete when a 'server.status' notification is
  /// received from the server with 'analyzing' set to false.
  ///
  /// The future will only be completed by 'server.status' notifications that
  /// are received after this function call, so it is safe to use this getter
  /// multiple times in one test; each time it is used it will wait afresh for
  /// analysis to finish.
  Future get analysisFinished {
    var completer = _analysisFinishedCompleter ??= Completer<void>();
    return completer.future;
  }

  /// Return a list of the paths of files that are currently being analyzed.
  List<String> get analyzedDartFiles {
    bool isAnalyzed(String filePath) {
      // TODO(brianwilkerson) This should use the path package to determine
      // inclusion, and needs to take exclusions into account.
      for (var includedRoot in _analysisRootIncludes) {
        if (filePath.startsWith(includedRoot)) {
          return true;
        }
      }
      return false;
    }

    var analyzedFiles = <String>[];
    for (var filePath in _analyzedFiles) {
      if (filePath.endsWith('.dart') && isAnalyzed(filePath)) {
        analyzedFiles.add(filePath);
      }
    }
    return analyzedFiles;
  }

  /// Return a table mapping the absolute paths of files to the most recent set
  /// of errors received for that file. The content of the map will not change
  /// when new sets of errors are received.
  ErrorMap get errorMap => ErrorMap.from(_errorMap);

  /// Compute a mapping from each of the file paths in the given list of
  /// [filePaths] to the list of errors in the file at that path.
  Future<ErrorMap> computeErrorMap(List<String> filePaths) async {
    var errorMap = ErrorMap();
    var futures = <Future>[];
    for (var filePath in filePaths) {
      var requestData = sendAnalysisGetErrors(filePath);
      futures.add(requestData.respondedTo.then((Response response) {
        if (response.result != null) {
          var result = AnalysisGetErrorsResult.fromResponse(response);
          errorMap[filePath] = result.errors;
        }
      }));
    }
    await Future.wait(futures);
    return errorMap;
  }

  /// Print information about the communications with the server.
  void printStatistics() {
    void writeSpaces(int count) {
      for (var i = 0; i < count; i++) {
        stdout.write(' ');
      }
    }

    //
    // Print information about the requests that were sent.
    //
    stdout.writeln('Request Counts');
    if (_requestDataMap.isEmpty) {
      stdout.writeln('  none');
    } else {
      var requestsByMethod = <String, List<RequestData>>{};
      _requestDataMap.values.forEach((RequestData requestData) {
        requestsByMethod
            .putIfAbsent(requestData.method, () => <RequestData>[])
            .add(requestData);
      });
      var keys = requestsByMethod.keys.toList();
      keys.sort();
      var maxCount = requestsByMethod.values
          .fold(0, (int count, List<RequestData> list) => count + list.length);
      var countWidth = maxCount.toString().length;
      for (var key in keys) {
        var requests = requestsByMethod[key]!;
        var noResponseCount = 0;
        var responseCount = 0;
        var minTime = -1;
        var maxTime = -1;
        var totalTime = 0;
        requests.forEach((RequestData data) {
          if (data.responseTime == null) {
            noResponseCount++;
          } else {
            responseCount++;
            var time = data.elapsedTime;
            minTime = minTime < 0 ? time : math.min(minTime, time);
            maxTime = math.max(maxTime, time);
            totalTime += time;
          }
        });
        var count = requests.length.toString();
        writeSpaces(countWidth - count.length);
        stdout.write('  ');
        stdout.write(count);
        stdout.write(' - ');
        stdout.write(key);
        if (noResponseCount > 0) {
          stdout.write(', ');
          stdout.write(noResponseCount);
          stdout.write(' with no response');
        }
        if (maxTime >= 0) {
          stdout.write(' (');
          stdout.write(minTime);
          stdout.write(', ');
          stdout.write(totalTime / responseCount);
          stdout.write(', ');
          stdout.write(maxTime);
          stdout.write(')');
        }
        stdout.writeln();
      }
    }
    //
    // Print information about the notifications that were received.
    //
    stdout.writeln();
    stdout.writeln('Notification Counts');
    if (_notificationCountMap.isEmpty) {
      stdout.writeln('  none');
    } else {
      var keys = _notificationCountMap.keys.toList();
      keys.sort();
      var maxCount = _notificationCountMap.values.fold(0, math.max);
      var countWidth = maxCount.toString().length;
      for (var key in keys) {
        var count = _notificationCountMap[key].toString();
        writeSpaces(countWidth - count.length);
        stdout.write('  ');
        stdout.write(count);
        stdout.write(' - ');
        stdout.writeln(key);
      }
    }
  }

  /// Remove any existing overlays.
  void removeAllOverlays() {
    var files = <String, Object>{};
    for (var path in filesWithOverlays) {
      files[path] = RemoveContentOverlay();
    }
    sendAnalysisUpdateContent(files);
  }

  RequestData sendAnalysisGetErrors(String file) {
    var params = AnalysisGetErrorsParams(file).toJson();
    return _send('analysis.getErrors', params);
  }

  RequestData sendAnalysisGetHover(String file, int offset) {
    var params = AnalysisGetHoverParams(file, offset).toJson();
    return _send('analysis.getHover', params);
  }

  RequestData sendAnalysisGetLibraryDependencies() {
    return _send('analysis.getLibraryDependencies', null);
  }

  RequestData sendAnalysisGetNavigation(String file, int offset, int length) {
    var params = AnalysisGetNavigationParams(file, offset, length).toJson();
    return _send('analysis.getNavigation', params);
  }

  RequestData sendAnalysisGetReachableSources(String file) {
    var params = AnalysisGetReachableSourcesParams(file).toJson();
    return _send('analysis.getReachableSources', params);
  }

  void sendAnalysisReanalyze() {
    var params = AnalysisReanalyzeParams().toJson();
    _send('analysis.reanalyze', params);
  }

  void sendAnalysisSetAnalysisRoots(
      List<String> included, List<String> excluded,
      {Map<String, String>? packageRoots}) {
    _analysisRootIncludes = included;
    var params = AnalysisSetAnalysisRootsParams(included, excluded,
            packageRoots: packageRoots)
        .toJson();
    _send('analysis.setAnalysisRoots', params);
  }

  void sendAnalysisSetGeneralSubscriptions(
      List<GeneralAnalysisService> subscriptions) {
    var params = AnalysisSetGeneralSubscriptionsParams(subscriptions).toJson();
    _send('analysis.setGeneralSubscriptions', params);
  }

  void sendAnalysisSetPriorityFiles(List<String> files) {
    var params = AnalysisSetPriorityFilesParams(files).toJson();
    _send('analysis.setPriorityFiles', params);
  }

  void sendAnalysisSetSubscriptions(
      Map<AnalysisService, List<String>> subscriptions) {
    var params = AnalysisSetSubscriptionsParams(subscriptions).toJson();
    _send('analysis.setSubscriptions', params);
  }

  void sendAnalysisUpdateContent(Map<String, Object> files) {
    files.forEach((path, overlay) {
      if (overlay is AddContentOverlay) {
        filesWithOverlays.add(path);
      } else if (overlay is RemoveContentOverlay) {
        filesWithOverlays.remove(path);
      }
    });
    var params = AnalysisUpdateContentParams(files).toJson();
    _send('analysis.updateContent', params);
  }

  void sendAnalysisUpdateOptions(AnalysisOptions options) {
    var params = AnalysisUpdateOptionsParams(options).toJson();
    _send('analysis.updateOptions', params);
  }

  void sendCompletionGetSuggestions(String file, int offset) {
    var params = CompletionGetSuggestionsParams(file, offset).toJson();
    _send('completion.getSuggestions', params);
  }

  RequestData sendDiagnosticGetDiagnostics() {
    return _send('diagnostic.getDiagnostics', null);
  }

  RequestData sendEditFormat(
      String file, int selectionOffset, int selectionLength,
      {int? lineLength}) {
    var params = EditFormatParams(file, selectionOffset, selectionLength,
            lineLength: lineLength)
        .toJson();
    return _send('edit.format', params);
  }

  RequestData sendEditGetAssists(String file, int offset, int length) {
    var params = EditGetAssistsParams(file, offset, length).toJson();
    return _send('edit.getAssists', params);
  }

  RequestData sendEditGetAvailableRefactorings(
      String file, int offset, int length) {
    var params =
        EditGetAvailableRefactoringsParams(file, offset, length).toJson();
    return _send('edit.getAvailableRefactorings', params);
  }

  RequestData sendEditGetFixes(String file, int offset) {
    var params = EditGetFixesParams(file, offset).toJson();
    return _send('edit.getFixes', params);
  }

  RequestData sendEditGetRefactoring(RefactoringKind kind, String file,
      int offset, int length, bool validateOnly,
      {RefactoringOptions? options}) {
    var params = EditGetRefactoringParams(
            kind, file, offset, length, validateOnly,
            options: options)
        .toJson();
    return _send('edit.getRefactoring', params);
  }

  RequestData sendEditOrganizeDirectives(String file) {
    var params = EditOrganizeDirectivesParams(file).toJson();
    return _send('edit.organizeDirectives', params);
  }

  RequestData sendEditSortMembers(String file) {
    var params = EditSortMembersParams(file).toJson();
    return _send('edit.sortMembers', params);
  }

  RequestData sendExecutionCreateContext(String contextRoot) {
    var params = ExecutionCreateContextParams(contextRoot).toJson();
    return _send('execution.createContext', params);
  }

  RequestData sendExecutionDeleteContext(String id) {
    var params = ExecutionDeleteContextParams(id).toJson();
    return _send('execution.deleteContext', params);
  }

  RequestData sendExecutionMapUri(String id, {String? file, String? uri}) {
    var params = ExecutionMapUriParams(id, file: file, uri: uri).toJson();
    return _send('execution.mapUri', params);
  }

  RequestData sendExecutionSetSubscriptions(
      List<ExecutionService> subscriptions) {
    var params = ExecutionSetSubscriptionsParams(subscriptions).toJson();
    return _send('execution.setSubscriptions', params);
  }

  void sendSearchFindElementReferences(
      String file, int offset, bool includePotential) {
    var params =
        SearchFindElementReferencesParams(file, offset, includePotential)
            .toJson();
    _send('search.findElementReferences', params);
  }

  void sendSearchFindMemberDeclarations(String name) {
    var params = SearchFindMemberDeclarationsParams(name).toJson();
    _send('search.findMemberDeclarations', params);
  }

  void sendSearchFindMemberReferences(String name) {
    var params = SearchFindMemberReferencesParams(name).toJson();
    _send('search.findMemberReferences', params);
  }

  void sendSearchFindTopLevelDeclarations(String pattern) {
    var params = SearchFindTopLevelDeclarationsParams(pattern).toJson();
    _send('search.findTopLevelDeclarations', params);
  }

  void sendSearchGetTypeHierarchy(String file, int offset, {bool? superOnly}) {
    var params =
        SearchGetTypeHierarchyParams(file, offset, superOnly: superOnly)
            .toJson();
    _send('search.getTypeHierarchy', params);
  }

  RequestData sendServerGetVersion() {
    return _send('server.getVersion', null);
  }

  void sendServerSetSubscriptions(List<ServerService> subscriptions) {
    var params = ServerSetSubscriptionsParams(subscriptions).toJson();
    _send('server.setSubscriptions', params);
  }

  void sendServerShutdown() {
    _send('server.shutdown', null);
  }

  /// Start the server and listen for communications from it.
  ///
  /// If [checked] is `true`, the server's VM will be running in checked mode.
  ///
  /// If [diagnosticPort] is not `null`, the server will serve status pages to
  /// the specified port.
  ///
  /// If [profileServer] is `true`, the server will be started with "--observe"
  /// and "--pause-isolates-on-exit", allowing the observatory to be used.
  ///
  /// If [useAnalysisHighlight2] is `true`, the server will use the new
  /// highlight APIs.
  Future<void> start(
      {bool checked = true,
      int? diagnosticPort,
      bool profileServer = false,
      String? sdkPath,
      int? servicesPort,
      bool useAnalysisHighlight2 = false}) async {
    if (_process != null) {
      throw Exception('Process already started');
    }
    var dartBinary = Platform.executable;
    var rootDir =
        _findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
    var serverPath = path.normalize(path.join(rootDir, 'bin', 'server.dart'));
    var arguments = <String>[];
    //
    // Add VM arguments.
    //
    if (profileServer) {
      if (servicesPort == null) {
        arguments.add('--observe');
      } else {
        arguments.add('--observe=$servicesPort');
      }
      arguments.add('--pause-isolates-on-exit');
    } else if (servicesPort != null) {
      arguments.add('--enable-vm-service=$servicesPort');
    }
    if (Platform.packageConfig != null) {
      arguments.add('--packages=${Platform.packageConfig}');
    }
    if (checked) {
      arguments.add('--checked');
    }
    //
    // Add the server executable.
    //
    arguments.add(serverPath);
    //
    // Add server arguments.
    //
    if (diagnosticPort != null) {
      arguments.add('--port');
      arguments.add(diagnosticPort.toString());
    }
    if (sdkPath != null) {
      arguments.add('--sdk=$sdkPath');
    }
    if (useAnalysisHighlight2) {
      arguments.add('--useAnalysisHighlight2');
    }
//    stdout.writeln('Launching $serverPath');
//    stdout.writeln('$dartBinary ${arguments.join(' ')}');
    _process = await Process.start(dartBinary, arguments);
    _process!.exitCode.then((int code) {
      if (code != 0) {
        throw StateError('Server terminated with exit code $code');
      }
    });
    _listenToOutput();
    var completer = Completer<void>();
    _serverConnectedCompleter = completer;
    return completer.future;
  }

  /// Find the root directory of the analysis_server package by proceeding
  /// upward to the 'test' dir, and then going up one more directory.
  String _findRoot(String pathname) {
    while (!['benchmark', 'test'].contains(path.basename(pathname))) {
      var parent = path.dirname(pathname);
      if (parent.length >= pathname.length) {
        throw Exception("Can't find root directory");
      }
      pathname = parent;
    }
    return path.dirname(pathname);
  }

  /// Handle a [notification] received from the server.
  void _handleNotification(Notification notification) {
    switch (notification.event) {
      case 'server.connected':
//        new ServerConnectedParams.fromNotification(notification);
        _serverConnectedCompleter!.complete(null);
        break;
      case 'server.error':
//        new ServerErrorParams.fromNotification(notification);
        throw StateError('Server error: ${notification.toJson()}');
      case 'server.status':
        if (_analysisFinishedCompleter != null) {
          var params = ServerStatusParams.fromNotification(notification);
          var analysis = params.analysis;
          if (analysis != null && !analysis.isAnalyzing) {
            _analysisFinishedCompleter!.complete(null);
          }
        }
        break;
      case 'analysis.analyzedFiles':
        var params = AnalysisAnalyzedFilesParams.fromNotification(notification);
        _analyzedFiles = params.directories;
        break;
      case 'analysis.errors':
        var params = AnalysisErrorsParams.fromNotification(notification);
        _errorMap.pathMap[params.file] = params.errors;
        break;
      case 'analysis.flushResults':
//        new AnalysisFlushResultsParams.fromNotification(notification);
        _errorMap.pathMap.clear();
        break;
      case 'analysis.folding':
//        new AnalysisFoldingParams.fromNotification(notification);
        break;
      case 'analysis.highlights':
//        new AnalysisHighlightsParams.fromNotification(notification);
        break;
      case 'analysis.implemented':
//        new AnalysisImplementedParams.fromNotification(notification);
        break;
      case 'analysis.invalidate':
//        new AnalysisInvalidateParams.fromNotification(notification);
        break;
      case 'analysis.navigation':
//        new AnalysisNavigationParams.fromNotification(notification);
        break;
      case 'analysis.occurrences':
//        new AnalysisOccurrencesParams.fromNotification(notification);
        break;
      case 'analysis.outline':
//        new AnalysisOutlineParams.fromNotification(notification);
        break;
      case 'analysis.overrides':
//        new AnalysisOverridesParams.fromNotification(notification);
        break;
      case 'completion.results':
//        new CompletionResultsParams.fromNotification(notification);
        break;
      case 'search.results':
//        new SearchResultsParams.fromNotification(notification);
        break;
      case 'execution.launchData':
//        new ExecutionLaunchDataParams.fromNotification(notification);
        break;
      default:
        throw StateError('Unhandled notification: ${notification.toJson()}');
    }
  }

  /// Handle a [response] received from the server.
  void _handleResponse(Response response) {
    var id = response.id.toString();
    var requestData = _requestDataMap[id]!;
    requestData.recordResponse(response);
//    switch (requestData.method) {
//      case "analysis.getErrors":
//        break;
//      case "analysis.getHover":
//        break;
//      case "analysis.getLibraryDependencies":
//        break;
//      case "analysis.getNavigation":
//        break;
//      case "analysis.getReachableSources":
//        break;
//      case "analysis.reanalyze":
//        break;
//      case "analysis.setAnalysisRoots":
//        break;
//      case "analysis.setGeneralSubscriptions":
//        break;
//      case "analysis.setPriorityFiles":
//        break;
//      case "analysis.setSubscriptions":
//        break;
//      case 'analysis.updateContent':
//        break;
//      case "analysis.updateOptions":
//        break;
//      case "completion.getSuggestions":
//        break;
//      case "diagnostic.getDiagnostics":
//        break;
//      case "edit.format":
//        break;
//      case "edit.getAssists":
//        break;
//      case "edit.getAvailableRefactorings":
//        break;
//      case "edit.getFixes":
//        break;
//      case "edit.getRefactoring":
//        break;
//      case "edit.organizeDirectives":
//        break;
//      case "edit.sortMembers":
//        break;
//      case "execution.createContext":
//        break;
//      case "execution.deleteContext":
//        break;
//      case "execution.mapUri":
//        break;
//      case "execution.setSubscriptions":
//        break;
//      case "search.findElementReferences":
//        break;
//      case "search.findMemberDeclarations":
//        break;
//      case "search.findMemberReferences":
//        break;
//      case "search.findTopLevelDeclarations":
//        break;
//      case "search.getTypeHierarchy":
//        break;
//      case "server.getVersion":
//        break;
//      case "server.setSubscriptions":
//        break;
//      case "server.shutdown":
//        break;
//      default:
//        throw new StateError('Unhandled response: ${response.toJson()}');
//    }
  }

  /// Handle a [line] of input read from stderr.
  void _handleStdErr(String line) {
    var trimmedLine = line.trim();
    logger?.log(fromStderr, '$trimmedLine');
    throw StateError('Message received on stderr: "$trimmedLine"');
  }

  /// Handle a [line] of input read from stdout.
  void _handleStdOut(String line) {
    /// Cast the given [value] to a Map, or throw an [ArgumentError] if the
    /// value cannot be cast.
    Map<String, Object?> asMap(Object value) {
      if (value is Map<String, Object?>) {
        return value;
      }
      throw ArgumentError('Expected a Map, found a ${value.runtimeType}');
    }

    var trimmedLine = line.trim();
    if (trimmedLine.isEmpty ||
        trimmedLine.startsWith('Observatory listening on ')) {
      return;
    }
    logger?.log(fromServer, '$trimmedLine');
    var message = asMap(json.decoder.convert(trimmedLine) as Object);
    if (message.containsKey('id')) {
      // The message is a response.
      var response = Response.fromJson(message)!;
      _handleResponse(response);
    } else {
      // The message is a notification.
      var notification = Notification.fromJson(message);
      var event = notification.event;
      _notificationCountMap[event] = (_notificationCountMap[event] ?? 0) + 1;
      _handleNotification(notification);
    }
  }

  /// Start listening to output from the server.
  void _listenToOutput() {
    /// Install the given [handler] to listen to transformed output from the
    /// given [stream].
    void installHandler(
        Stream<List<int>> stream, void Function(String) handler) {
      stream
          .transform(Utf8Codec().decoder)
          .transform(LineSplitter())
          .listen(handler);
    }

    installHandler(_process!.stdout, _handleStdOut);
    installHandler(_process!.stderr, _handleStdErr);
  }

  /// Send a command to the server. An 'id' will be automatically assigned.
  RequestData _send(String method, Map<String, dynamic>? params) {
    var id = '${_nextId++}';
    var requestData = RequestData(id, method, params, currentTime);
    _requestDataMap[id] = requestData;
    var command = <String, dynamic>{'id': id, 'method': method};
    if (params != null) {
      command['params'] = params;
    }
    var line = json.encode(command);
    _process!.stdin.add(utf8.encoder.convert('$line\n'));
    logger?.log(fromClient, '$line');
    return requestData;
  }
}
