// 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 messageText = e is DebugAdapterException ? e.message : '$e';
      final errorMessage = Message(
        id: ErrorMessageType.general,
        format: '{message}\n{stack}',
        variables: {'message': messageText, 'stack': '$s'},
      );
      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,
    InitializeRequestArguments 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(PauseResponseBody) 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,
        InitializeRequestArguments.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,
        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 == '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),
        );
  }
}
