// 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 'dart:math' as math;

import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/analysis_server_abstract.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/protocol_server.dart' hide Element;
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;

/// An abstract implementation of a request handler.
abstract class AbstractRequestHandler
    with RequestHandlerMixin<AnalysisServer>
    implements RequestHandler {
  /// The analysis server that is using this handler to process requests.
  @override
  final AnalysisServer server;

  /// Initialize a newly created request handler to be associated with the given
  /// analysis [server].
  AbstractRequestHandler(this.server);
}

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,
      int timeout = 500}) async {
    // TODO(brianwilkerson) requestParameters might need to be required.
    var endTime = DateTime.now().millisecondsSinceEpoch + timeout;
    var responses = <plugin.Response>[];
    for (var pluginInfo in futures.keys) {
      var future = futures[pluginInfo];
      try {
        var startTime = DateTime.now().millisecondsSinceEpoch;
        var response = await future
            .timeout(Duration(milliseconds: math.max(endTime - startTime, 0)));
        if (response.error != null) {
          // TODO(brianwilkerson) Report the error to the plugin manager.
          server.instrumentationService.logPluginError(
              pluginInfo.data,
              response.error.code.name,
              response.error.message,
              response.error.stackTrace);
        } 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;
  }
}
