//===--- ClangdLSPServer.h - LSP server --------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H

#include "ClangdServer.h"
#include "GlobalCompilationDatabase.h"
#include "LSPBinder.h"
#include "Protocol.h"
#include "Transport.h"
#include "support/Context.h"
#include "support/MemoryTree.h"
#include "support/Path.h"
#include "support/Threading.h"
#include "llvm/Support/JSON.h"
#include <chrono>
#include <cstddef>
#include <memory>
#include <optional>
#include <vector>

namespace clang {
namespace clangd {

/// This class exposes ClangdServer's capabilities via Language Server Protocol.
///
/// MessageHandler binds the implemented LSP methods (e.g. onInitialize) to
/// corresponding JSON-RPC methods ("initialize").
/// The server also supports $/cancelRequest (MessageHandler provides this).
class ClangdLSPServer : private ClangdServer::Callbacks,
                        private LSPBinder::RawOutgoing {
public:
  struct Options : ClangdServer::Options {
    /// Supplies configuration (overrides ClangdServer::ContextProvider).
    config::Provider *ConfigProvider = nullptr;
    /// Look for compilation databases, rather than using compile commands
    /// set via LSP (extensions) only.
    bool UseDirBasedCDB = true;
    /// The offset-encoding to use, or std::nullopt to negotiate it over LSP.
    std::optional<OffsetEncoding> Encoding;
    /// If set, periodically called to release memory.
    /// Consider malloc_trim(3)
    std::function<void()> MemoryCleanup = nullptr;

    /// Per-feature options. Generally ClangdServer lets these vary
    /// per-request, but LSP allows limited/no customizations.
    clangd::CodeCompleteOptions CodeComplete;
    MarkupKind SignatureHelpDocumentationFormat = MarkupKind::PlainText;
    clangd::RenameOptions Rename;
    /// Returns true if the tweak should be enabled.
    std::function<bool(const Tweak &)> TweakFilter = [](const Tweak &T) {
      return !T.hidden(); // only enable non-hidden tweaks.
    };

    /// Limit the number of references returned (0 means no limit).
    size_t ReferencesLimit = 0;
  };

  ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
                  const ClangdLSPServer::Options &Opts);
  /// The destructor blocks on any outstanding background tasks.
  ~ClangdLSPServer();

  /// Run LSP server loop, communicating with the Transport provided in the
  /// constructor. This method must not be executed more than once.
  ///
  /// \return Whether we shut down cleanly with a 'shutdown' -> 'exit' sequence.
  bool run();

  /// Profiles resource-usage.
  void profile(MemoryTree &MT) const;

private:
  // Implement ClangdServer::Callbacks.
  void onDiagnosticsReady(PathRef File, llvm::StringRef Version,
                          std::vector<Diag> Diagnostics) override;
  void onFileUpdated(PathRef File, const TUStatus &Status) override;
  void onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) override;
  void onSemanticsMaybeChanged(PathRef File) override;

  // LSP methods. Notifications have signature void(const Params&).
  // Calls have signature void(const Params&, Callback<Response>).
  void onInitialize(const InitializeParams &, Callback<llvm::json::Value>);
  void onInitialized(const InitializedParams &);
  void onShutdown(const NoParams &, Callback<std::nullptr_t>);
  void onSync(const NoParams &, Callback<std::nullptr_t>);
  void onDocumentDidOpen(const DidOpenTextDocumentParams &);
  void onDocumentDidChange(const DidChangeTextDocumentParams &);
  void onDocumentDidClose(const DidCloseTextDocumentParams &);
  void onDocumentDidSave(const DidSaveTextDocumentParams &);
  void onAST(const ASTParams &, Callback<std::optional<ASTNode>>);
  void onDocumentOnTypeFormatting(const DocumentOnTypeFormattingParams &,
                                  Callback<std::vector<TextEdit>>);
  void onDocumentRangeFormatting(const DocumentRangeFormattingParams &,
                                 Callback<std::vector<TextEdit>>);
  void onDocumentFormatting(const DocumentFormattingParams &,
                            Callback<std::vector<TextEdit>>);
  // The results are serialized 'vector<DocumentSymbol>' if
  // SupportsHierarchicalDocumentSymbol is true and 'vector<SymbolInformation>'
  // otherwise.
  void onDocumentSymbol(const DocumentSymbolParams &,
                        Callback<llvm::json::Value>);
  void onFoldingRange(const FoldingRangeParams &,
                      Callback<std::vector<FoldingRange>>);
  void onCodeAction(const CodeActionParams &, Callback<llvm::json::Value>);
  void onCompletion(const CompletionParams &, Callback<CompletionList>);
  void onSignatureHelp(const TextDocumentPositionParams &,
                       Callback<SignatureHelp>);
  void onGoToDeclaration(const TextDocumentPositionParams &,
                         Callback<std::vector<Location>>);
  void onGoToDefinition(const TextDocumentPositionParams &,
                        Callback<std::vector<Location>>);
  void onGoToType(const TextDocumentPositionParams &,
                  Callback<std::vector<Location>>);
  void onGoToImplementation(const TextDocumentPositionParams &,
                            Callback<std::vector<Location>>);
  void onReference(const ReferenceParams &, Callback<std::vector<ReferenceLocation>>);
  void onSwitchSourceHeader(const TextDocumentIdentifier &,
                            Callback<std::optional<URIForFile>>);
  void onDocumentHighlight(const TextDocumentPositionParams &,
                           Callback<std::vector<DocumentHighlight>>);
  void onFileEvent(const DidChangeWatchedFilesParams &);
  void onWorkspaceSymbol(const WorkspaceSymbolParams &,
                         Callback<std::vector<SymbolInformation>>);
  void onPrepareRename(const TextDocumentPositionParams &,
                       Callback<std::optional<Range>>);
  void onRename(const RenameParams &, Callback<WorkspaceEdit>);
  void onHover(const TextDocumentPositionParams &,
               Callback<std::optional<Hover>>);
  void onPrepareTypeHierarchy(const TypeHierarchyPrepareParams &,
                              Callback<std::vector<TypeHierarchyItem>>);
  void onSuperTypes(const ResolveTypeHierarchyItemParams &,
                    Callback<std::optional<std::vector<TypeHierarchyItem>>>);
  void onSubTypes(const ResolveTypeHierarchyItemParams &,
                  Callback<std::vector<TypeHierarchyItem>>);
  void onTypeHierarchy(const TypeHierarchyPrepareParams &,
                       Callback<llvm::json::Value>);
  void onResolveTypeHierarchy(const ResolveTypeHierarchyItemParams &,
                              Callback<llvm::json::Value>);
  void onPrepareCallHierarchy(const CallHierarchyPrepareParams &,
                              Callback<std::vector<CallHierarchyItem>>);
  void onCallHierarchyIncomingCalls(
      const CallHierarchyIncomingCallsParams &,
      Callback<std::vector<CallHierarchyIncomingCall>>);
  void onCallHierarchyOutgoingCalls(
      const CallHierarchyOutgoingCallsParams &,
      Callback<std::vector<CallHierarchyOutgoingCall>>);
  void onClangdInlayHints(const InlayHintsParams &,
                          Callback<llvm::json::Value>);
  void onInlayHint(const InlayHintsParams &, Callback<std::vector<InlayHint>>);
  void onChangeConfiguration(const DidChangeConfigurationParams &);
  void onSymbolInfo(const TextDocumentPositionParams &,
                    Callback<std::vector<SymbolDetails>>);
  void onSelectionRange(const SelectionRangeParams &,
                        Callback<std::vector<SelectionRange>>);
  void onDocumentLink(const DocumentLinkParams &,
                      Callback<std::vector<DocumentLink>>);
  void onSemanticTokens(const SemanticTokensParams &, Callback<SemanticTokens>);
  void onSemanticTokensDelta(const SemanticTokensDeltaParams &,
                             Callback<SemanticTokensOrDelta>);
  /// This is a clangd extension. Provides a json tree representing memory usage
  /// hierarchy.
  void onMemoryUsage(const NoParams &, Callback<MemoryTree>);
  void onCommand(const ExecuteCommandParams &, Callback<llvm::json::Value>);

  /// Implement commands.
  void onCommandApplyEdit(const WorkspaceEdit &, Callback<llvm::json::Value>);
  void onCommandApplyTweak(const TweakArgs &, Callback<llvm::json::Value>);

  /// Outgoing LSP calls.
  LSPBinder::OutgoingMethod<ApplyWorkspaceEditParams,
                            ApplyWorkspaceEditResponse>
      ApplyWorkspaceEdit;
  LSPBinder::OutgoingNotification<ShowMessageParams> ShowMessage;
  LSPBinder::OutgoingNotification<PublishDiagnosticsParams> PublishDiagnostics;
  LSPBinder::OutgoingNotification<FileStatus> NotifyFileStatus;
  LSPBinder::OutgoingMethod<WorkDoneProgressCreateParams, std::nullptr_t>
      CreateWorkDoneProgress;
  LSPBinder::OutgoingNotification<ProgressParams<WorkDoneProgressBegin>>
      BeginWorkDoneProgress;
  LSPBinder::OutgoingNotification<ProgressParams<WorkDoneProgressReport>>
      ReportWorkDoneProgress;
  LSPBinder::OutgoingNotification<ProgressParams<WorkDoneProgressEnd>>
      EndWorkDoneProgress;
  LSPBinder::OutgoingMethod<NoParams, std::nullptr_t> SemanticTokensRefresh;

  void applyEdit(WorkspaceEdit WE, llvm::json::Value Success,
                 Callback<llvm::json::Value> Reply);

  void bindMethods(LSPBinder &, const ClientCapabilities &Caps);
  std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);

  /// Checks if completion request should be ignored. We need this due to the
  /// limitation of the LSP. Per LSP, a client sends requests for all "trigger
  /// character" we specify, but for '>' and ':' we need to check they actually
  /// produce '->' and '::', respectively.
  bool shouldRunCompletion(const CompletionParams &Params) const;

  void applyConfiguration(const ConfigurationSettings &Settings);

  /// Runs profiling and exports memory usage metrics if tracing is enabled and
  /// profiling hasn't happened recently.
  void maybeExportMemoryProfile();
  PeriodicThrottler ShouldProfile;

  /// Run the MemoryCleanup callback if it's time.
  /// This method is thread safe.
  void maybeCleanupMemory();
  PeriodicThrottler ShouldCleanupMemory;

  /// Since initialization of CDBs and ClangdServer is done lazily, the
  /// following context captures the one used while creating ClangdLSPServer and
  /// passes it to above mentioned object instances to make sure they share the
  /// same state.
  Context BackgroundContext;

  /// Used to indicate that the 'shutdown' request was received from the
  /// Language Server client.
  bool ShutdownRequestReceived = false;

  /// Used to indicate the ClangdLSPServer is being destroyed.
  std::atomic<bool> IsBeingDestroyed = {false};

  std::mutex FixItsMutex;
  typedef std::map<clangd::Diagnostic, std::vector<Fix>, LSPDiagnosticCompare>
      DiagnosticToReplacementMap;
  /// Caches FixIts per file and diagnostics
  llvm::StringMap<DiagnosticToReplacementMap> FixItsMap;
  // Last semantic-tokens response, for incremental requests.
  std::mutex SemanticTokensMutex;
  llvm::StringMap<SemanticTokens> LastSemanticTokens;

  // Most code should not deal with Transport, callMethod, notify directly.
  // Use LSPBinder to handle incoming and outgoing calls.
  clangd::Transport &Transp;
  class MessageHandler;
  std::unique_ptr<MessageHandler> MsgHandler;
  std::mutex TranspWriter;

  void callMethod(StringRef Method, llvm::json::Value Params,
                  Callback<llvm::json::Value> CB) override;
  void notify(StringRef Method, llvm::json::Value Params) override;

  LSPBinder::RawHandlers Handlers;

  const ThreadsafeFS &TFS;
  /// Options used for diagnostics.
  ClangdDiagnosticOptions DiagOpts;
  /// The supported kinds of the client.
  SymbolKindBitset SupportedSymbolKinds;
  /// The supported completion item kinds of the client.
  CompletionItemKindBitset SupportedCompletionItemKinds;
  /// Whether the client supports CodeAction response objects.
  bool SupportsCodeAction = false;
  /// From capabilities of textDocument/documentSymbol.
  bool SupportsHierarchicalDocumentSymbol = false;
  /// Whether the client supports showing file status.
  bool SupportFileStatus = false;
  /// Whether the client supports attaching a container string to references.
  bool SupportsReferenceContainer = false;
  /// Which kind of markup should we use in textDocument/hover responses.
  MarkupKind HoverContentFormat = MarkupKind::PlainText;
  /// Whether the client supports offsets for parameter info labels.
  bool SupportsOffsetsInSignatureHelp = false;
  std::mutex BackgroundIndexProgressMutex;
  enum class BackgroundIndexProgress {
    // Client doesn't support reporting progress. No transitions possible.
    Unsupported,
    // The queue is idle, and the client has no progress bar.
    // Can transition to Creating when we have some activity.
    Empty,
    // We've requested the client to create a progress bar.
    // Meanwhile, the state is buffered in PendingBackgroundIndexProgress.
    Creating,
    // The client has a progress bar, and we can send it updates immediately.
    Live,
  } BackgroundIndexProgressState = BackgroundIndexProgress::Unsupported;
  // The progress to send when the progress bar is created.
  // Only valid in state Creating.
  BackgroundQueue::Stats PendingBackgroundIndexProgress;
  /// LSP extension: skip WorkDoneProgressCreate, just send progress streams.
  bool BackgroundIndexSkipCreate = false;

  Options Opts;
  // The CDB is created by the "initialize" LSP method.
  std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
  // CDB is BaseCDB plus any commands overridden via LSP extensions.
  std::optional<OverlayCDB> CDB;
  // The ClangdServer is created by the "initialize" LSP method.
  std::optional<ClangdServer> Server;
};
} // namespace clangd
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
