// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/domain_abstract.dart';
import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';

/// Instances of the class [CompletionDomainHandler] implement a
/// [RequestHandler] that handles requests in the completion domain.
class CompletionDomainHandler extends AbstractRequestHandler {
  /// The maximum number of performance measurements to keep.
  static const int performanceListMaxLength = 50;

  /// The completion services that the client is currently subscribed.
  final Set<CompletionService> subscriptions = <CompletionService>{};

  /// The next completion response id.
  int _nextCompletionId = 0;

  /// Code completion performance for the last completion operation.
  CompletionPerformance performance;

  /// A list of code completion performance measurements for the latest
  /// completion operation up to [performanceListMaxLength] measurements.
  final RecentBuffer<CompletionPerformance> performanceList =
      RecentBuffer<CompletionPerformance>(performanceListMaxLength);

  /// The current request being processed or `null` if none.
  CompletionRequestImpl _currentRequest;

  /// The identifiers of the latest `getSuggestionDetails` request.
  /// We use it to abort previous requests.
  int _latestGetSuggestionDetailsId = 0;

  /// Initialize a new request handler for the given [server].
  CompletionDomainHandler(AnalysisServer server) : super(server);

  /// Compute completion results for the given request and append them to the
  /// stream. Clients should not call this method directly as it is
  /// automatically called when a client listens to the stream returned by
  /// [results]. Subclasses should override this method, append at least one
  /// result to the [controller], and close the controller stream once complete.
  Future<CompletionResult> computeSuggestions(
    OperationPerformanceImpl perf,
    CompletionRequestImpl request,
    CompletionGetSuggestionsParams params,
    Set<ElementKind> includedElementKinds,
    Set<String> includedElementNames,
    List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags,
  ) async {
    //
    // Allow plugins to start computing fixes.
    //
    Map<PluginInfo, Future<plugin.Response>> pluginFutures;
    plugin.CompletionGetSuggestionsParams requestParams;
    var file = params.file;
    var offset = params.offset;
    var driver = server.getAnalysisDriver(file);
    if (driver != null) {
      requestParams = plugin.CompletionGetSuggestionsParams(file, offset);
      pluginFutures = server.pluginManager
          .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
    }
    //
    // Compute completions generated by server.
    //
    var suggestions = <CompletionSuggestion>[];
    if (request.result != null) {
      const COMPUTE_SUGGESTIONS_TAG = 'computeSuggestions';
      await perf.runAsync(COMPUTE_SUGGESTIONS_TAG, (perf) async {
        var manager = DartCompletionManager(
          dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
            request.result,
          ),
          includedElementKinds: includedElementKinds,
          includedElementNames: includedElementNames,
          includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
        );

        var contributorTag = 'computeSuggestions - ${manager.runtimeType}';
        await perf.runAsync(contributorTag, (performance) async {
          try {
            suggestions.addAll(
              await manager.computeSuggestions(performance, request),
            );
          } on AbortCompletion {
            suggestions.clear();
          }
        });
      });
    }
    // TODO (danrubel) if request is obsolete (processAnalysisRequest returns
    // false) then send empty results

    //
    // Add the completions produced by plugins to the server-generated list.
    //
    if (pluginFutures != null) {
      var responses = await waitForResponses(pluginFutures,
          requestParameters: requestParams, timeout: 100);
      for (var response in responses) {
        var result =
            plugin.CompletionGetSuggestionsResult.fromResponse(response);
        if (result.results != null && result.results.isNotEmpty) {
          if (suggestions.isEmpty) {
            request.replacementOffset = result.replacementOffset;
            request.replacementLength = result.replacementLength;
          } else if (request.replacementOffset != result.replacementOffset &&
              request.replacementLength != result.replacementLength) {
            server.instrumentationService
                .logError('Plugin completion-results dropped due to conflicting'
                    ' replacement offset/length: ${result.toJson()}');
            continue;
          }
          suggestions.addAll(result.results);
        }
      }
    }
    //
    // Return the result.
    //
    return CompletionResult(
        request.replacementOffset, request.replacementLength, suggestions);
  }

  /// Return the suggestions that should be presented in the YAML [file] at the
  /// given [offset].
  YamlCompletionResults computeYamlSuggestions(String file, int offset) {
    var provider = server.resourceProvider;
    if (AnalysisEngine.isAnalysisOptionsFileName(file)) {
      var generator = AnalysisOptionsGenerator(provider);
      return generator.getSuggestions(file, offset);
    }
    var fileName = provider.pathContext.basename(file);
    if (fileName == AnalysisEngine.PUBSPEC_YAML_FILE) {
      var generator = PubspecGenerator(provider);
      return generator.getSuggestions(file, offset);
    } else if (fileName == AnalysisEngine.FIX_DATA_FILE) {
      var generator = FixDataGenerator(provider);
      return generator.getSuggestions(file, offset);
    }
    return const YamlCompletionResults.empty();
  }

  /// Process a `completion.getSuggestionDetails` request.
  void getSuggestionDetails(Request request) async {
    var params = CompletionGetSuggestionDetailsParams.fromRequest(request);

    var file = params.file;
    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
      return;
    }

    var libraryId = params.id;
    var library = server.declarationsTracker.getLibrary(libraryId);
    if (library == null) {
      server.sendResponse(Response.invalidParameter(
        request,
        'libraryId',
        'No such library: $libraryId',
      ));
      return;
    }

    // The label might be `MyEnum.myValue`, but we import only `MyEnum`.
    var requestedName = params.label;
    if (requestedName.contains('.')) {
      requestedName = requestedName.substring(
        0,
        requestedName.indexOf('.'),
      );
    }

    const timeout = Duration(milliseconds: 1000);
    var timer = Stopwatch()..start();
    var id = ++_latestGetSuggestionDetailsId;
    while (id == _latestGetSuggestionDetailsId && timer.elapsed < timeout) {
      try {
        var analysisDriver = server.getAnalysisDriver(file);
        var session = analysisDriver.currentSession;

        var completion = params.label;
        var builder = ChangeBuilder(session: session);
        await builder.addDartFileEdit(file, (builder) {
          var result = builder.importLibraryElement(library.uri);
          if (result.prefix != null) {
            completion = '${result.prefix}.$completion';
          }
        });

        server.sendResponse(
          CompletionGetSuggestionDetailsResult(
            completion,
            change: builder.sourceChange,
          ).toResponse(request.id),
        );
        return;
      } on InconsistentAnalysisException {
        // Loop around to try again.
      }
    }

    // Timeout or abort, send the empty response.
    server.sendResponse(
      CompletionGetSuggestionDetailsResult('').toResponse(request.id),
    );
  }

  @override
  Response handleRequest(Request request) {
    if (!server.options.featureSet.completion) {
      return Response.invalidParameter(
        request,
        'request',
        'The completion feature is not enabled',
      );
    }

    return runZonedGuarded(() {
      var requestName = request.method;

      if (requestName == COMPLETION_REQUEST_GET_SUGGESTION_DETAILS) {
        getSuggestionDetails(request);
        return Response.DELAYED_RESPONSE;
      } else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) {
        processRequest(request);
        return Response.DELAYED_RESPONSE;
      } else if (requestName == COMPLETION_REQUEST_SET_SUBSCRIPTIONS) {
        return setSubscriptions(request);
      }
      return null;
    }, (exception, stackTrace) {
      AnalysisEngine.instance.instrumentationService.logException(
          CaughtException.withMessage(
              'Failed to handle completion domain request: ${request.method}',
              exception,
              stackTrace));
    });
  }

  void ifMatchesRequestClear(CompletionRequest completionRequest) {
    if (_currentRequest == completionRequest) {
      _currentRequest = null;
    }
  }

  /// Process a `completion.getSuggestions` request.
  Future<void> processRequest(Request request) async {
    performance = CompletionPerformance();

    await performance.runRequestOperation((perf) async {
      // extract and validate params
      var params = CompletionGetSuggestionsParams.fromRequest(request);
      var file = params.file;
      var offset = params.offset;

      if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
        return;
      }
      if (file.endsWith('.yaml')) {
        // Return the response without results.
        var completionId = (_nextCompletionId++).toString();
        server.sendResponse(CompletionGetSuggestionsResult(completionId)
            .toResponse(request.id));
        // Send a notification with results.
        final suggestions = computeYamlSuggestions(file, offset);
        sendCompletionNotification(
          completionId,
          suggestions.replacementOffset,
          suggestions.replacementLength,
          suggestions.suggestions,
          null,
          null,
          null,
          null,
        );
        return;
      }

      var resolvedUnit = await server.getResolvedUnit(file);
      server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
      if (resolvedUnit?.state == ResultState.VALID) {
        if (offset < 0 || offset > resolvedUnit.content.length) {
          server.sendResponse(Response.invalidParameter(
              request,
              'params.offset',
              'Expected offset between 0 and source length inclusive,'
                  ' but found $offset'));
          return;
        }

        recordRequest(performance, file, resolvedUnit.content, offset);
      }
      var completionRequest =
          CompletionRequestImpl(resolvedUnit, offset, performance);

      var completionId = (_nextCompletionId++).toString();

      setNewRequest(completionRequest);

      // initial response without results
      server.sendResponse(
          CompletionGetSuggestionsResult(completionId).toResponse(request.id));

      // If the client opted into using available suggestion sets,
      // create the kinds set, so signal the completion manager about opt-in.
      Set<ElementKind> includedElementKinds;
      Set<String> includedElementNames;
      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
      if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
        includedElementKinds = <ElementKind>{};
        includedElementNames = <String>{};
        includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
      }

      // Compute suggestions in the background
      try {
        var result = await computeSuggestions(
          perf,
          completionRequest,
          params,
          includedElementKinds,
          includedElementNames,
          includedSuggestionRelevanceTags,
        );
        String libraryFile;
        var includedSuggestionSets = <IncludedSuggestionSet>[];
        if (includedElementKinds != null && resolvedUnit != null) {
          libraryFile = resolvedUnit.libraryElement.source.fullName;
          server.sendNotification(
            createExistingImportsNotification(resolvedUnit),
          );
          computeIncludedSetList(
            server.declarationsTracker,
            resolvedUnit,
            includedSuggestionSets,
            includedElementNames,
          );
        }

        const SEND_NOTIFICATION_TAG = 'send notification';
        perf.run(SEND_NOTIFICATION_TAG, (_) {
          sendCompletionNotification(
            completionId,
            result.replacementOffset,
            result.replacementLength,
            result.suggestions,
            libraryFile,
            includedSuggestionSets,
            includedElementKinds?.toList(),
            includedSuggestionRelevanceTags,
          );
        });

        performance.suggestionCount = result.suggestions.length;
      } finally {
        ifMatchesRequestClear(completionRequest);
      }
    });
  }

  /// If tracking code completion performance over time, then
  /// record addition information about the request in the performance record.
  void recordRequest(CompletionPerformance performance, String path,
      String content, int offset) {
    performance.path = path;
    if (performanceListMaxLength == 0) {
      return;
    }
    performance.setContentsAndOffset(content, offset);
    performanceList.add(performance);
  }

  /// Send completion notification results.
  void sendCompletionNotification(
    String completionId,
    int replacementOffset,
    int replacementLength,
    Iterable<CompletionSuggestion> results,
    String libraryFile,
    List<IncludedSuggestionSet> includedSuggestionSets,
    List<ElementKind> includedElementKinds,
    List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags,
  ) {
    server.sendNotification(
      CompletionResultsParams(
        completionId,
        replacementOffset,
        replacementLength,
        results,
        true,
        libraryFile: libraryFile,
        includedSuggestionSets: includedSuggestionSets,
        includedElementKinds: includedElementKinds,
        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
      ).toNotification(),
    );
  }

  void setNewRequest(CompletionRequest completionRequest) {
    _abortCurrentRequest();
    _currentRequest = completionRequest;
  }

  /// Implement the 'completion.setSubscriptions' request.
  Response setSubscriptions(Request request) {
    var params = CompletionSetSubscriptionsParams.fromRequest(request);

    subscriptions.clear();
    subscriptions.addAll(params.subscriptions);

    if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
      var data = server.declarationsTrackerData;
      var soFarLibraries = data.startListening((change) {
        server.sendNotification(
          createCompletionAvailableSuggestionsNotification(
            change.changed,
            change.removed,
          ),
        );
      });
      server.sendNotification(
        createCompletionAvailableSuggestionsNotification(
          soFarLibraries,
          [],
        ),
      );
    } else {
      server.declarationsTrackerData.stopListening();
    }

    return CompletionSetSubscriptionsResult().toResponse(request.id);
  }

  /// Abort the current completion request, if any.
  void _abortCurrentRequest() {
    if (_currentRequest != null) {
      _currentRequest.abort();
      _currentRequest = null;
    }
  }
}

/// The result of computing suggestions for code completion.
class CompletionResult {
  /// The length of the text to be replaced if the remainder of the identifier
  /// containing the cursor is to be replaced when the suggestion is applied
  /// (that is, the number of characters in the existing identifier).
  final int replacementLength;

  /// The offset of the start of the text to be replaced. This will be different
  /// than the offset used to request the completion suggestions if there was a
  /// portion of an identifier before the original offset. In particular, the
  /// replacementOffset will be the offset of the beginning of said identifier.
  final int replacementOffset;

  /// The suggested completions.
  final List<CompletionSuggestion> suggestions;

  CompletionResult(
      this.replacementOffset, this.replacementLength, this.suggestions);
}
