// Copyright (c) 2021, 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:dap/dap.dart';
import 'package:meta/meta.dart';

import 'constants.dart';
import 'protocol_stream.dart';

typedef _FromJsonHandler<T> = T Function(Map<String, Object?>);
typedef _NullableFromJsonHandler<T> = T? Function(Map<String, Object?>?);
typedef RequestHandler<TArg, TResp> = Future<void> Function(
    Request, TArg, void Function(TResp));
typedef _VoidArgRequestHandler<TArg> = Future<void> Function(
    Request, TArg, void Function(void));
typedef _VoidNoArgRequestHandler<TArg> = Future<void> Function(
    Request, TArg, void Function());

/// A base class for debug adapters.
///
/// Communicates over a [ByteStreamServerChannel] and turns messages into
/// appropriate method calls/events.
///
/// This class does not implement any DA functionality, only message handling.
abstract class BaseDebugAdapter<TLaunchArgs extends LaunchRequestArguments,
    TAttachArgs extends AttachRequestArguments> {
  int _sequence = 1;
  final ByteStreamServerChannel _channel;

  /// Completers for requests that are sent from the server back to the editor
  /// such as `runInTerminal`.
  final _serverToClientRequestCompleters = <int, Completer<Object?>>{};

  BaseDebugAdapter(this._channel, {Function? onError}) {
    _channel.listen(_handleIncomingMessage, onError: onError);
  }

  /// Parses arguments for [attachRequest] into a type of [TAttachArgs].
  ///
  /// This method must be implemented by the implementing class using a class
  /// that corresponds to the arguments it expects (these may differ between
  /// Dart CLI, Dart tests, Flutter, Flutter tests).
  TAttachArgs Function(Map<String, Object?>) get parseAttachArgs;

  /// Parses arguments for [launchRequest] into a type of [TLaunchArgs].
  ///
  /// This method must be implemented by the implementing class using a class
  /// that corresponds to the arguments it expects (these may differ between
  /// Dart CLI, Dart tests, Flutter, Flutter tests).
  TLaunchArgs Function(Map<String, Object?>) get parseLaunchArgs;

  Future<void> attachRequest(
    Request request,
    TAttachArgs args,
    void Function() sendResponse,
  );

  Future<void> configurationDoneRequest(
    Request request,
    ConfigurationDoneArguments? args,
    void Function() sendResponse,
  );

  Future<void> continueRequest(
    Request request,
    ContinueArguments args,
    void Function(ContinueResponseBody) sendResponse,
  );

  @mustCallSuper
  Future<void> customRequest(
    Request request,
    RawRequestArguments? args,
    void Function(Object?) sendResponse,
  ) async {
    throw DebugAdapterException('Unknown command ${request.command}');
  }

  Future<void> disconnectRequest(
    Request request,
    DisconnectArguments? args,
    void Function() sendResponse,
  );

  Future<void> evaluateRequest(
    Request request,
    EvaluateArguments args,
    void Function(EvaluateResponseBody) sendResponse,
  );

  /// Calls [handler] for an incoming request, using [fromJson] to parse its
  /// arguments from the request.
  ///
  /// [handler] will be provided a function [sendResponse] that it can use to
  /// sends its response without needing to build a [Response] from fields on
  /// the request.
  ///
  /// [handler] must _always_ call [sendResponse], even if the response does not
  /// require a body.
  ///
  /// [responseWriter] is a function that will be provided the response to be
  /// sent on the stream. It is critical that this sends the response
  /// synchronously because additional events may be sent by handlers that must
  /// come after it.
  ///
  /// If [handler] throws, its exception will be sent as an error response.
  Future<void> handle<TArg, TResp>(
    Request request,
    RequestHandler<TArg, TResp> handler,
    TArg Function(Map<String, Object?>) fromJson,
    void Function(Response) responseWriter,
  ) async {
    try {
      final args = request.arguments != null
          ? fromJson(request.arguments as Map<String, Object?>)
          // arguments are only valid to be null then TArg is nullable.
          : null as TArg;

      // Because handlers may need to send responses before they have finished
      // executing (for example, initializeRequest needs to send its response
      // before sending InitializedEvent()), we pass in a function `sendResponse`
      // rather than using a return value.
      var sendResponseCalled = false;
      void sendResponse(TResp responseBody) {
        assert(!sendResponseCalled,
            'sendResponse was called multiple times by ${request.command}');
        sendResponseCalled = true;
        final response = Response(
          success: true,
          requestSeq: request.seq,
          seq: _sequence++,
          command: request.command,
          body: responseBody,
        );
        responseWriter(response);
      }

      await handler(request, args, sendResponse);
      assert(sendResponseCalled,
          'sendResponse was not called in ${request.command}');
    } catch (e, s) {
      // TODO(helin24): Consider adding an error type to DebugAdapterException.
      final isDapException = e is DebugAdapterException;
      final messageText = isDapException ? e.message : '$e';
      final errorMessage = Message(
        id: ErrorMessageType.general,
        format: '{message}',
        // We include stack in the payload for debugging, but we don't include
        // it in format above because we don't want it used to build the error
        // shown to the user.
        variables: {'message': messageText, 'stack': '$s'},
        // DAP specification did not specify how to handle the case where
        // showUser does not exist. VSCode defaults to true, but some other
        // systems might default it to false.
        // Only show errors that are intended to be shown to the user. These
        // include any errors in LaunchRequest or AttachRequest.
        showUser: isDapException && e.showToUser == true,
      );
      final response = Response(
        success: false,
        requestSeq: request.seq,
        seq: _sequence++,
        command: request.command,
        message: messageText,
        body: ErrorResponseBody(error: errorMessage),
      );
      responseWriter(response);
    }
  }

  Future<void> initializeRequest(
    Request request,
    DartInitializeRequestArguments args,
    void Function(Capabilities) sendResponse,
  );

  Future<void> launchRequest(
    Request request,
    TLaunchArgs args,
    void Function() sendResponse,
  );

  Future<void> nextRequest(
    Request request,
    NextArguments args,
    void Function() sendResponse,
  );

  Future<void> pauseRequest(
    Request request,
    PauseArguments args,
    void Function() sendResponse,
  );

  Future<void> restartFrameRequest(
    Request request,
    RestartFrameArguments args,
    void Function() sendResponse,
  );

  Future<void> restartRequest(
    Request request,
    RestartArguments? args,
    void Function() sendResponse,
  );

  Future<void> scopesRequest(
    Request request,
    ScopesArguments args,
    void Function(ScopesResponseBody) sendResponse,
  );

  /// Sends an event, lookup up the event type based on the runtimeType of
  /// [body].
  void sendEvent(EventBody body, {String? eventType}) {
    final event = Event(
      seq: _sequence++,
      event: eventType ?? eventTypes[body.runtimeType]!,
      body: body,
    );
    sendEventToChannel(event);
  }

  void sendEventToChannel(Event event) {
    _channel.sendEvent(event);
  }

  /// Sends a request to the client, looking up the request type based on the
  /// runtimeType of [arguments].
  Future<Object?> sendRequest(RequestArguments arguments) {
    final request = Request(
      seq: _sequence++,
      command: commandTypes[arguments.runtimeType]!,
      arguments: arguments,
    );

    // Store a completer to be used when a response comes back.
    final completer = Completer<Object?>();
    _serverToClientRequestCompleters[request.seq] = completer;
    _channel.sendRequest(request);

    return completer.future;
  }

  Future<void> setBreakpointsRequest(
      Request request,
      SetBreakpointsArguments args,
      void Function(SetBreakpointsResponseBody) sendResponse);

  Future<void> setExceptionBreakpointsRequest(
    Request request,
    SetExceptionBreakpointsArguments args,
    void Function(SetExceptionBreakpointsResponseBody) sendResponse,
  );

  Future<void> sourceRequest(
    Request request,
    SourceArguments args,
    void Function(SourceResponseBody) sendResponse,
  );

  Future<void> stackTraceRequest(
    Request request,
    StackTraceArguments args,
    void Function(StackTraceResponseBody) sendResponse,
  );

  Future<void> stepInRequest(
    Request request,
    StepInArguments args,
    void Function() sendResponse,
  );

  Future<void> stepOutRequest(
    Request request,
    StepOutArguments args,
    void Function() sendResponse,
  );

  Future<void> terminateRequest(
    Request request,
    TerminateArguments? args,
    void Function() sendResponse,
  );

  Future<void> threadsRequest(
    Request request,
    void args,
    void Function(ThreadsResponseBody) sendResponse,
  );

  Future<void> variablesRequest(
    Request request,
    VariablesArguments args,
    void Function(VariablesResponseBody) sendResponse,
  );

  /// Wraps a fromJson handler for requests that allow null arguments.
  _NullableFromJsonHandler<T> _allowNullArg<T extends RequestArguments>(
    _FromJsonHandler<T> fromJson,
  ) {
    return (data) => data == null ? null : fromJson(data);
  }

  /// Handles incoming messages from the client editor.
  void _handleIncomingMessage(ProtocolMessage message) {
    if (message is Request) {
      handleIncomingRequest(message, _channel.sendResponse);
    } else if (message is Response) {
      _handleIncomingResponse(message);
    } else {
      throw DebugAdapterException('Unknown Protocol message ${message.type}');
    }
  }

  /// Handles an incoming request, calling the appropriate method to handle it.
  ///
  /// [responseWriter] is a function that will be provided the response to be
  /// sent on the stream. It is critical that this sends the response
  /// synchronously because additional events may be sent by handlers that must
  /// come after it.
  void handleIncomingRequest(
    Request request,
    void Function(Response) responseWriter,
  ) {
    if (request.command == 'initialize') {
      handle(
        request,
        initializeRequest,
        DartInitializeRequestArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'launch') {
      handle(
        request,
        _withVoidResponse(launchRequest),
        parseLaunchArgs,
        responseWriter,
      );
    } else if (request.command == 'attach') {
      handle(
        request,
        _withVoidResponse(attachRequest),
        parseAttachArgs,
        responseWriter,
      );
    } else if (request.command == 'restart') {
      handle(
        request,
        _withVoidResponse(restartRequest),
        _allowNullArg(RestartArguments.fromJson),
        responseWriter,
      );
    } else if (request.command == 'terminate') {
      handle(
        request,
        _withVoidResponse(terminateRequest),
        _allowNullArg(TerminateArguments.fromJson),
        responseWriter,
      );
    } else if (request.command == 'disconnect') {
      handle(
        request,
        _withVoidResponse(disconnectRequest),
        _allowNullArg(DisconnectArguments.fromJson),
        responseWriter,
      );
    } else if (request.command == 'configurationDone') {
      handle(
        request,
        _withVoidResponse(configurationDoneRequest),
        _allowNullArg(ConfigurationDoneArguments.fromJson),
        responseWriter,
      );
    } else if (request.command == 'setBreakpoints') {
      handle(
        request,
        setBreakpointsRequest,
        SetBreakpointsArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'setExceptionBreakpoints') {
      handle(
        request,
        setExceptionBreakpointsRequest,
        SetExceptionBreakpointsArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'pause') {
      handle(
        request,
        _withVoidResponse(pauseRequest),
        PauseArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'continue') {
      handle(
        request,
        continueRequest,
        ContinueArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'next') {
      handle(
        request,
        _withVoidResponse(nextRequest),
        NextArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'stepIn') {
      handle(
        request,
        _withVoidResponse(stepInRequest),
        StepInArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'stepOut') {
      handle(
        request,
        _withVoidResponse(stepOutRequest),
        StepOutArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'restartFrame') {
      handle(
        request,
        _withVoidResponse(restartFrameRequest),
        RestartFrameArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'threads') {
      handle(
        request,
        threadsRequest,
        _voidArgs,
        responseWriter,
      );
    } else if (request.command == 'stackTrace') {
      handle(
        request,
        stackTraceRequest,
        StackTraceArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'source') {
      handle(
        request,
        sourceRequest,
        SourceArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'scopes') {
      handle(
        request,
        scopesRequest,
        ScopesArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'variables') {
      handle(
        request,
        variablesRequest,
        VariablesArguments.fromJson,
        responseWriter,
      );
    } else if (request.command == 'evaluate') {
      handle(
        request,
        evaluateRequest,
        EvaluateArguments.fromJson,
        responseWriter,
      );
    } else {
      handle(
        request,
        customRequest,
        _allowNullArg(RawRequestArguments.fromJson),
        responseWriter,
      );
    }
  }

  void _handleIncomingResponse(Response response) {
    final completer =
        _serverToClientRequestCompleters.remove(response.requestSeq);

    if (response.success) {
      completer?.complete(response.body);
    } else {
      completer?.completeError(
        response.message ?? 'Request ${response.requestSeq} failed',
      );
    }
  }

  /// Shuts down the debug adapter by closing the underlying communication
  /// channel.
  void shutdown() {
    _channel.close();
  }

  /// Helpers for requests that have `void` arguments. The supplied args are
  /// ignored.
  void _voidArgs(Map<String, Object?>? args) {}

  /// Helper that converts a handler with no response value to one that has
  /// passes an unused arg so that `Function()` can be passed to a function
  /// accepting `Function<T>(T x)` where `T` happens to be `void`.
  ///
  /// This allows handlers to simply call sendResponse() where they have no
  /// return value but need to send a valid response.
  _VoidArgRequestHandler<TArg> _withVoidResponse<TArg>(
    _VoidNoArgRequestHandler<TArg> handler,
  ) {
    return (request, arg, sendResponse) => handler(
          request,
          arg,
          () => sendResponse(null),
        );
  }
}
