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

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

import 'package:analysis_server/src/analysis_server_abstract.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;

mixin RequestHandlerMixin<T extends AbstractAnalysisServer> {
  /// The analysis server that is using this handler to process requests.
  T get server;

  /// Given a mapping from plugins to futures that will complete when the plugin
  /// has responded to a request, wait for a finite amount of time for each of
  /// the plugins to respond. Return a list of the responses from each of the
  /// plugins. If a plugin fails to return a response, notify the plugin manager
  /// associated with the server so that non-responsive plugins can be killed or
  /// restarted. The [timeout] is the maximum amount of time that will be spent
  /// waiting for plugins to respond.
  Future<List<plugin.Response>> waitForResponses(
    Map<PluginInfo, Future<plugin.Response>> futures, {
    plugin.RequestParams? requestParameters,
    Duration timeout = const Duration(milliseconds: 500),
  }) async {
    // TODO(brianwilkerson) requestParameters might need to be required.
    var timer = Stopwatch()..start();
    var responses = <plugin.Response>[];
    for (var entry in futures.entries) {
      var pluginInfo = entry.key;
      var future = entry.value;
      try {
        var response = await future.timeout(timeout - timer.elapsed);
        var error = response.error;
        if (error != null) {
          // TODO(brianwilkerson) Report the error to the plugin manager.
          server.instrumentationService.logPluginError(
              pluginInfo.data,
              error.code.name,
              error.message,
              error.stackTrace ?? StackTrace.current.toString());
        } else {
          responses.add(response);
        }
      } on TimeoutException {
        // TODO(brianwilkerson) Report the timeout to the plugin manager.
        server.instrumentationService.logPluginTimeout(
            pluginInfo.data,
            JsonEncoder()
                .convert(requestParameters?.toRequest('-').toJson() ?? {}));
      } catch (exception, stackTrace) {
        // TODO(brianwilkerson) Report the exception to the plugin manager.
        server.instrumentationService
            .logPluginException(pluginInfo.data, exception, stackTrace);
      }
    }
    return responses;
  }
}
