// Copyright (c) 2020, 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 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analyzer_plugin/protocol/protocol.dart';

class LspNotificationManager extends AbstractNotificationManager {
  /// The analysis server, used to fetch LineInfo in order to map plugin
  /// data structures to LSP structures.
  late LspAnalysisServer
      server; // Set externally immediately after construction

  LspNotificationManager(super.pathContext);

  /// Sends errors for a file to the client.
  @override
  void sendAnalysisErrors(
      String filePath, List<protocol.AnalysisError> errors) {
    // Currently these diagnostics are always sent to the editor client, so
    // use those client capabilities.
    var clientCapabilities = server.editorClientCapabilities;
    var diagnostics = errors
        .map((error) => pluginToDiagnostic(
              server.uriConverter,
              (path) => server.getLineInfo(path),
              error,
              supportedTags: clientCapabilities?.diagnosticTags,
              clientSupportsCodeDescription:
                  clientCapabilities?.diagnosticCodeDescription ?? false,
            ))
        .toList();

    server.publishDiagnostics(filePath, diagnostics);
  }

  @override
  void sendFoldingRegions(
      String filePath, List<protocol.FoldingRegion> mergedFolding) {
    // In LSP, folding regions are requested by the client with
    // 'textDocument/foldingRange' rather than pushed so there's no need
    // to do anything here. Results are merged by the base class and provided
    // on-demand.
  }

  @override
  void sendHighlightRegions(
      String filePath, List<protocol.HighlightRegion> mergedHighlights) {
    // TODO(dantup): implement sendHighlightRegions
  }

  @override
  void sendNavigations(protocol.AnalysisNavigationParams mergedNavigations) {
    // In LSP, occurrences are requested by the client with 'textDocument/definition'
    // and 'textDocument/references' rather than pushed so there's no need
    // to do anything here. Results are merged by the base class and provided
    // on-demand.
  }

  @override
  void sendOccurrences(
      String filePath, List<protocol.Occurrences> mergedOccurrences) {
    // In LSP, occurrences are requested by the client with
    // 'textDocument/documentHighlight' rather than pushed so there's no need
    // to do anything here. Results are merged by the base class and provided
    // on-demand.
  }

  @override
  void sendOutlines(String filePath, List<protocol.Outline> mergedOutlines) {
    // In LSP, outlines are requested by the client with
    // 'textDocument/documentSymbol' rather than pushed so there's no need
    // to do anything here. Results are merged by the base class and provided
    // on-demand.
  }

  @override
  void sendPluginErrorNotification(Notification notification) {
    // TODO(dantup): implement sendPluginErrorNotification
  }
}
