// 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 IntializedMessageHandler extends MessageHandler<InitializedParams, void> {
  final List<String> openWorkspacePaths;
  IntializedMessageHandler(
    LspAnalysisServer server,
    this.openWorkspacePaths,
  ) : super(server);
  Method get handlesMessage => Method.initialized;

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

  ErrorOr<void> handle(InitializedParams params, CancellationToken token) {
    server.messageHandler = new InitializedStateMessageHandler(
      server,
    );

    _performDynamicRegistration();

    if (!server.initializationOptions.onlyAnalyzeProjectsWithOpenFiles) {
      server.setAnalysisRoots(openWorkspacePaths);
    }

    return success();
  }

  /// If the client supports dynamic registrations we can tell it what methods
  /// we support for which documents. For example, this allows us to ask for
  /// file edits for .dart as well as pubspec.yaml but only get hover/completion
  /// calls for .dart. This functionality may not be supported by the client, in
  /// which case they will use the ServerCapabilities to know which methods we
  /// support and it will be up to them to decide which file types they will
  /// send requests for.
  Future<void> _performDynamicRegistration() async {
    final dartFiles = DocumentFilter('dart', 'file', null);
    final pubspecFile = DocumentFilter('yaml', 'file', '**/pubspec.yaml');
    final analysisOptionsFile =
        DocumentFilter('yaml', 'file', '**/analysis_options.yaml');
    final allTypes = [dartFiles, pubspecFile, analysisOptionsFile];

    // TODO(dantup): When we support plugins, we will need to collect their
    // requirements too. For example, the Angular plugin might wish to add HTML
    // `DocumentFilter('html', 'file', null)` to many of these requests.

    int _lastRegistrationId = 1;
    final registrations = <Registration>[];

    /// Helper for creating registrations with IDs.
    void register(bool condition, Method method, [ToJsonable options]) {
      if (condition == true) {
        registrations.add(Registration(
            (_lastRegistrationId++).toString(), method.toJson(), options));
      }
    }

    final textCapabilities = server.clientCapabilities?.textDocument;

    register(
      textCapabilities?.synchronization?.dynamicRegistration,
      Method.textDocument_didOpen,
      TextDocumentRegistrationOptions(allTypes),
    );
    register(
      textCapabilities?.synchronization?.dynamicRegistration,
      Method.textDocument_didClose,
      TextDocumentRegistrationOptions(allTypes),
    );
    register(
      textCapabilities?.synchronization?.dynamicRegistration,
      Method.textDocument_didChange,
      TextDocumentChangeRegistrationOptions(
          TextDocumentSyncKind.Incremental, allTypes),
    );
    register(
      server.clientCapabilities?.textDocument?.completion?.dynamicRegistration,
      Method.textDocument_completion,
      CompletionRegistrationOptions(
        dartCompletionTriggerCharacters,
        null,
        true,
        [dartFiles],
      ),
    );
    register(
      textCapabilities?.hover?.dynamicRegistration,
      Method.textDocument_hover,
      TextDocumentRegistrationOptions([dartFiles]),
    );
    register(
      textCapabilities?.signatureHelp?.dynamicRegistration,
      Method.textDocument_signatureHelp,
      SignatureHelpRegistrationOptions(
          dartSignatureHelpTriggerCharacters, [dartFiles]),
    );
    register(
      server.clientCapabilities?.textDocument?.references?.dynamicRegistration,
      Method.textDocument_references,
      TextDocumentRegistrationOptions([dartFiles]),
    );
    register(
      textCapabilities?.documentHighlight?.dynamicRegistration,
      Method.textDocument_documentHighlight,
      TextDocumentRegistrationOptions([dartFiles]),
    );
    register(
      textCapabilities?.documentSymbol?.dynamicRegistration,
      Method.textDocument_documentSymbol,
      TextDocumentRegistrationOptions([dartFiles]),
    );
    register(
      server.clientCapabilities?.textDocument?.formatting?.dynamicRegistration,
      Method.textDocument_formatting,
      TextDocumentRegistrationOptions([dartFiles]),
    );
    register(
      textCapabilities?.onTypeFormatting?.dynamicRegistration,
      Method.textDocument_onTypeFormatting,
      DocumentOnTypeFormattingRegistrationOptions(
        dartTypeFormattingCharacters.first,
        dartTypeFormattingCharacters.skip(1).toList(),
        [dartFiles],
      ),
    );
    register(
      server.clientCapabilities?.textDocument?.definition?.dynamicRegistration,
      Method.textDocument_definition,
      TextDocumentRegistrationOptions([dartFiles]),
    );
    register(
      textCapabilities?.implementation?.dynamicRegistration,
      Method.textDocument_implementation,
      TextDocumentRegistrationOptions([dartFiles]),
    );
    register(
      server.clientCapabilities?.textDocument?.codeAction?.dynamicRegistration,
      Method.textDocument_codeAction,
      CodeActionRegistrationOptions(
          [dartFiles], DartCodeActionKind.serverSupportedKinds),
    );
    register(
      textCapabilities?.rename?.dynamicRegistration,
      Method.textDocument_rename,
      RenameRegistrationOptions(true, [dartFiles]),
    );
    register(
      textCapabilities?.foldingRange?.dynamicRegistration,
      Method.textDocument_foldingRange,
      TextDocumentRegistrationOptions([dartFiles]),
    );

    // Only send the registration request if we have at least one (since
    // otherwise we don't know that the client supports registerCapability).
    if (registrations.isNotEmpty) {
      final registrationResponse = await server.sendRequest(
        Method.client_registerCapability,
        RegistrationParams(registrations),
      );

      if (registrationResponse.error != null) {
        server.logErrorToClient(
          'Failed to register capabilities with client: '
          '(${registrationResponse.error.code}) '
          '${registrationResponse.error.message}',
        );
      }
    }
  }
}
