// 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/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 implements RequestHandler {
  /**
   * The analysis server that is using this handler to process requests.
   */
  final AnalysisServer server;

  /**
   * Initialize a newly created request handler to be associated with the given
   * analysis [server].
   */
  AbstractRequestHandler(this.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) Determine whether this await is necessary.
    await null;
    // TODO(brianwilkerson) requestParameters might need to be required.
    int endTime = new DateTime.now().millisecondsSinceEpoch + timeout;
    List<plugin.Response> responses = <plugin.Response>[];
    for (PluginInfo pluginInfo in futures.keys) {
      Future<plugin.Response> future = futures[pluginInfo];
      try {
        int startTime = new DateTime.now().millisecondsSinceEpoch;
        plugin.Response response = await future.timeout(
            new 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,
            new 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;
  }
}
