// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';

class InitializeMessageHandler
    extends MessageHandler<InitializeParams, InitializeResult> {
  InitializeMessageHandler(LspAnalysisServer server) : super(server);

  Method get handlesMessage => Method.initialize;

  @override
  LspJsonHandler<InitializeParams> get jsonHandler =>
      InitializeParams.jsonHandler;

  ErrorOr<InitializeResult> handle(InitializeParams params) {
    final openWorkspacePaths = <String>[];

    // The onlyAnalyzeProjectsWithOpenFiles flag allows opening huge folders
    // without setting them as analysis roots. Instead, analysis roots will be
    // based only on the open files.
    final onlyAnalyzeProjectsWithOpenFiles = params.initializationOptions !=
            null
        ? params.initializationOptions['onlyAnalyzeProjectsWithOpenFiles'] ==
            true
        : false;

    if (!onlyAnalyzeProjectsWithOpenFiles) {
      if (params.workspaceFolders != null) {
        params.workspaceFolders.forEach((wf) {
          openWorkspacePaths.add(Uri.parse(wf.uri).toFilePath());
        });
      }
      if (params.rootUri != null) {
        openWorkspacePaths.add(Uri.parse(params.rootUri).toFilePath());
        // ignore: deprecated_member_use_from_same_package
      } else if (params.rootPath != null) {
        // This is deprecated according to LSP spec, but we still want to support
        // it in case older clients send us it.
        // ignore: deprecated_member_use_from_same_package
        openWorkspacePaths.add(params.rootPath);
      }
    }

    server.handleClientConnection(params.capabilities);
    server.messageHandler = new InitializingStateMessageHandler(
        server, openWorkspacePaths, onlyAnalyzeProjectsWithOpenFiles);

    final codeActionLiteralSupport =
        params.capabilities.textDocument?.codeAction?.codeActionLiteralSupport;

    final renameOptionsSupport =
        params.capabilities.textDocument?.rename?.prepareSupport ?? false;

    server.capabilities = new ServerCapabilities(
        Either2<TextDocumentSyncOptions, num>.t1(new TextDocumentSyncOptions(
          true,
          TextDocumentSyncKind.Incremental,
          false,
          false,
          null,
        )),
        true, // hoverProvider
        new CompletionOptions(
          false,
          // Set the characters that will cause the editor to automatically
          // trigger completion.
          // TODO(dantup): There are several characters that we want to conditionally
          // allow to trigger completion, but they can only be added when the completion
          // provider is able to handle them in context:
          //
          //    {   trigger if being typed in a string immediately after a $
          //    '   trigger if the opening quote for an import/export
          //    "   trigger if the opening quote for an import/export
          //    /   trigger if as part of a path in an import/export
          //    \   trigger if as part of a path in an import/export
          //    :   don't trigger when typing case expressions (`case x:`)
          //
          // Additionally, we need to prefix `filterText` on completion items
          // with spaces for those that can follow whitespace (eg. `foo` in
          // `myArg: foo`) to ensure they're not filtered away when the user
          // types space.
          //
          // See https://github.com/Dart-Code/Dart-Code/blob/68d1cd271e88a785570257d487adbdec17abd6a3/src/providers/dart_completion_item_provider.ts#L36-L64
          // for the VS Code implementation of this.
          r'''.=($'''.split(''),
        ),
        new SignatureHelpOptions(
          // TODO(dantup): Signature help triggering is even more sensitive to
          // bad chars, so we'll need to implement the logic described here:
          // https://github.com/dart-lang/sdk/issues/34241
          [],
        ),
        true, // definitionProvider
        null,
        null,
        true, // referencesProvider
        true, // documentHighlightProvider
        true, // documentSymbolProvider
        true, // workspaceSymbolProvider
        // "The `CodeActionOptions` return type is only valid if the client
        // signals code action literal support via the property
        // `textDocument.codeAction.codeActionLiteralSupport`."
        codeActionLiteralSupport != null
            ? Either2<bool, CodeActionOptions>.t2(
                new CodeActionOptions(DartCodeActionKind.serverSupportedKinds))
            : Either2<bool, CodeActionOptions>.t1(true),
        null,
        true, // documentFormattingProvider
        false, // documentRangeFormattingProvider
        new DocumentOnTypeFormattingOptions('}', [';']),
        renameOptionsSupport
            ? Either2<bool, RenameOptions>.t2(new RenameOptions(true))
            : Either2<bool, RenameOptions>.t1(true),
        null,
        null,
        true, // foldingRangeProvider
        new ExecuteCommandOptions(Commands.serverSupportedCommands),
        null, // declarationProvider
        new ServerCapabilitiesWorkspace(
            new ServerCapabilitiesWorkspaceFolders(true, true)),
        null);

    return success(new InitializeResult(server.capabilities));
  }
}
