// Copyright (c) 2014, 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.

/// Support for client code that needs to interact with the requests, responses
/// and notifications that are part of the analysis server's wire protocol.
library;

import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
import 'package:analyzer/src/utilities/cancellation.dart';

export 'package:analyzer_plugin/protocol/protocol.dart' show Enum;

/// A message that was received from the client.
///
/// A client can send a [Request], a [Notification], or a [Response] to a
/// request that the server sent to it.
///
/// Clients may not extend, implement or mix-in this class.
sealed class ClientMessage {}

/// A notification about an event that occurred.
///
/// Notifications are usually sent by the server, but a client can send some of
/// them to the server too (currently only `lsp.notification`).
///
/// Clients may not extend, implement or mix-in this class.
class Notification extends ClientMessage {
  /// The name of the JSON attribute containing the name of the event that
  /// triggered the notification.
  static const String eventAttributeName = 'event';

  /// The name of the JSON attribute containing the result values.
  static const String paramsAttributeName = 'params';

  /// The name of the event that triggered the notification.
  final String event;

  /// A table mapping the names of notification parameters to their values, or
  /// `null` if there are no notification parameters.
  final Map<String, Object?>? params;

  /// Initialize a newly created [Notification] to have the given [event] name.
  /// If [params] is provided, it will be used as the params; otherwise no
  /// params will be used.
  new(this.event, [this.params]);

  /// Initialize a newly created instance based on the given JSON data.
  factory fromJson(Map<Object?, Object?> json) {
    return Notification(
      json[Notification.eventAttributeName] as String,
      json[Notification.paramsAttributeName] as Map<String, Object?>?,
    );
  }

  /// Returns a table representing the structure of the JSON object that will be
  /// sent to the client to represent this response.
  Map<String, Object> toJson() => {
    eventAttributeName: event,
    paramsAttributeName: ?params,
  };

  /// Returns a notification parsed from the given JSON [result], or `null` if
  /// the data is not a valid JSON representation of a notification. The data is
  /// expected to have the following format:
  ///
  ///     {
  ///       'event': String,
  ///       'params': {
  ///         parameter_name: value
  ///       }
  ///     }
  ///
  /// where the parameters are optional.
  ///
  /// Unlike [Notification.fromJson], this does not throw for data that is not a
  /// notification, so it can be used to test whether some data is one.
  static Notification? tryFromJson(Map<String, Object?> result) {
    var event = result[Notification.eventAttributeName];
    if (event is! String) {
      return null;
    }
    var params = result[Notification.paramsAttributeName];
    if (params is! Map<String, Object?>?) {
      return null;
    }
    return Notification(event, params);
  }
}

/// A request that was received from the client.
///
/// Clients may not extend, implement or mix-in this class.
class Request extends RequestOrResponse {
  /// The name of the JSON attribute containing the id of the request.
  static const String idAttributeName = 'id';

  /// The name of the JSON attribute containing the name of the request.
  static const String methodAttributeName = 'method';

  /// The name of the JSON attribute containing the request parameters.
  static const String paramsAttributeName = 'params';

  /// The name of the optional JSON attribute indicating the time (milliseconds
  /// since epoch) at which the client made the request.
  static const String clientRequestTimeAttributeName = 'clientRequestTime';

  /// The unique identifier used to identify this request.
  @override
  final String id;

  /// The method being requested.
  final String method;

  /// A table mapping the names of request parameters to their values.
  final Map<String, Object?> params;

  /// The time (milliseconds since epoch) at which the client made the request
  /// or `null` if this information is not provided by the client.
  final int? clientRequestTime;

  /// Initialize a newly created [Request] to have the given [id] and [method]
  /// name. If [params] is supplied, it is used as the "params" map for the
  /// request. Otherwise an empty "params" map is allocated.
  new(
    this.id,
    this.method, [
    Map<String, Object?>? params,
    this.clientRequestTime,
  ]) : params = params ?? <String, Object?>{};

  @override
  int get hashCode {
    return id.hashCode;
  }

  /// Returns the amount of time (in milliseconds) since the client sent this
  /// request or `null` if the client did not provide [clientRequestTime].
  int? get timeSinceRequest {
    var clientRequestTime = this.clientRequestTime;
    return clientRequestTime != null
        ? DateTime.now().millisecondsSinceEpoch - clientRequestTime
        : null;
  }

  @override
  bool operator ==(Object other) {
    return other is Request &&
        id == other.id &&
        method == other.method &&
        clientRequestTime == other.clientRequestTime &&
        _equalMaps(params, other.params);
  }

  /// Returns a table representing the structure of the JSON object that will be
  /// sent to the client to represent this response.
  Map<String, Object> toJson() => {
    idAttributeName: id,
    methodAttributeName: method,
    if (params.isNotEmpty) paramsAttributeName: params,
    clientRequestTimeAttributeName: ?clientRequestTime,
  };

  bool _equalLists(List<Object?> first, List<Object?> second) {
    var length = first.length;
    if (length != second.length) {
      return false;
    }
    for (var i = 0; i < length; i++) {
      if (!_equalObjects(first[i], second[i])) {
        return false;
      }
    }
    return true;
  }

  bool _equalMaps(Map<Object?, Object?> first, Map<Object?, Object?> second) {
    if (first.length != second.length) {
      return false;
    }
    for (var key in first.keys) {
      if (!second.containsKey(key)) {
        return false;
      }
      if (!_equalObjects(first[key], second[key])) {
        return false;
      }
    }
    return true;
  }

  bool _equalObjects(Object? first, Object? second) {
    if (first == null) {
      return second == null;
    }
    if (second == null) {
      return false;
    }
    if (first is Map) {
      if (second is Map) {
        return _equalMaps(first, second);
      }
      return false;
    }
    if (first is List) {
      if (second is List) {
        return _equalLists(first, second);
      }
      return false;
    }
    return first == second;
  }

  /// Returns a request parsed from the given JSON [result], or `null` if the
  /// data is not a valid JSON representation of a request. The data is expected
  /// to have the following format:
  ///
  ///     {
  ///       'clientRequestTime': millisecondsSinceEpoch
  ///       'id': String,
  ///       'method': methodName,
  ///       'params': {
  ///         parameter_name: value
  ///       }
  ///     }
  ///
  /// where both the parameters and `clientRequestTime` are optional.
  ///
  /// The parameters can contain any number of name/value pairs. The
  /// `clientRequestTime` must be an int representing the time at which the
  /// client issued the request (milliseconds since epoch).
  static Request? fromJson(Map<String, Object?> result) {
    var id = result[Request.idAttributeName];
    var method = result[Request.methodAttributeName];
    if (id is! String || method is! String) {
      return null;
    }
    var time = result[Request.clientRequestTimeAttributeName];
    if (time is! int?) {
      return null;
    }
    var params = result[Request.paramsAttributeName];
    if (params is Map<String, Object?>?) {
      return Request(id, method, params, time);
    } else {
      return null;
    }
  }
}

/// An exception that occurred during the handling of a request that requires
/// that an error be returned to the client.
///
/// Clients may not extend, implement or mix-in this class.
class RequestFailure implements Exception {
  /// The response to be returned as a result of the failure.
  final Response response;

  /// Initialize a newly created exception to return the given response.
  new(this.response);
}

/// An object that can handle requests and produce responses for them.
///
/// Clients may not extend, implement or mix-in this class.
abstract class RequestHandler {
  /// Attempt to handle the given [request]. If the request is not recognized by
  /// this handler, return `null` so that other handlers will be given a chance
  /// to handle it. Otherwise, return the response that should be passed back to
  /// the client.
  Response? handleRequest(Request request, CancellationToken cancellationToken);
}

/// A request or response that was received from the client.
///
/// Clients may not extend, implement or mix-in this class.
sealed class RequestOrResponse extends ClientMessage {
  /// The unique identifier associated with this request or response.
  String get id;
}

/// A response to a request.
///
/// Clients may not extend, implement or mix-in this class.
class Response extends RequestOrResponse {
  /// The name of the JSON attribute containing the id of the request for which
  /// this is a response.
  static const String idAttributeName = 'id';

  /// The name of the JSON attribute containing the error message.
  static const String errorAttributeName = 'error';

  /// The name of the JSON attribute containing the result values.
  static const String resultAttributeName = 'result';

  /// The unique identifier used to identify the request that this response is
  /// associated with.
  @override
  final String id;

  /// The error that was caused by attempting to handle the request, or `null`
  /// if there was no error.
  final RequestError? error;

  /// A table mapping the names of result fields to their values.  Should be
  /// `null` if there is no result to send.
  Map<String, Object?>? result;

  /// Initialize a newly created instance to represent a response to a request
  /// with the given [id].  If [result] is provided, it will be used as the
  /// result; otherwise an empty result will be used.  If an [error] is provided
  /// then the response will represent an error condition.
  new(this.id, {this.result, this.error});

  /// Initialize a newly created instance to represent the CONTENT_MODIFIED
  /// error condition.
  new contentModified(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.CONTENT_MODIFIED,
          'File was modified before the operation completed.',
        ),
      );

  /// Create and return the `DEBUG_PORT_COULD_NOT_BE_OPENED` error response.
  new debugPortCouldNotBeOpened(Request request, Object? error)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.DEBUG_PORT_COULD_NOT_BE_OPENED,
          '$error',
        ),
      );

  /// Initialize a newly created instance to represent the FILE_NOT_ANALYZED
  /// error condition.
  new fileNotAnalyzed(Request request, String file)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.FILE_NOT_ANALYZED,
          'File is not analyzed: $file.',
        ),
      );

  /// Initialize a newly created instance to represent the FORMAT_INVALID_FILE
  /// error condition.
  new formatInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.FORMAT_INVALID_FILE,
          'Error during `${request.method}`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the FORMAT_WITH_ERROR
  /// error condition.
  new formatWithErrors(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.FORMAT_WITH_ERRORS,
          'Error during `edit.format`: source contains syntax errors.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_ERRORS_INVALID_FILE error condition.
  new getErrorsInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_ERRORS_INVALID_FILE,
          'Error during `analysis.getErrors`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_FIXES_INVALID_FILE error condition.
  new getFixesInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_FIXES_INVALID_FILE,
          'Error during `edit.getFixes`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_IMPORTED_ELEMENTS_INVALID_FILE error condition.
  new getImportedElementsInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_IMPORTED_ELEMENTS_INVALID_FILE,
          'Error during `analysis.getImportedElements`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_NAVIGATION_INVALID_FILE error condition.
  new getNavigationInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_NAVIGATION_INVALID_FILE,
          'Error during `analysis.getNavigation`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_REACHABLE_SOURCES_INVALID_FILE error condition.
  new getReachableSourcesInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE,
          'Error during `analysis.getReachableSources`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_SIGNATURE_INVALID_FILE error condition.
  new getSignatureInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_SIGNATURE_INVALID_FILE,
          'Error during `analysis.getSignature`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_SIGNATURE_INVALID_OFFSET error condition.
  new getSignatureInvalidOffset(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_SIGNATURE_INVALID_OFFSET,
          'Error during `analysis.getSignature`: invalid offset.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// GET_SIGNATURE_UNKNOWN_FUNCTION error condition.
  new getSignatureUnknownFunction(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.GET_SIGNATURE_UNKNOWN_FUNCTION,
          'Error during `analysis.getSignature`: unknown function.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// IMPORT_ELEMENTS_INVALID_FILE error condition.
  new importElementsInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.IMPORT_ELEMENTS_INVALID_FILE,
          'Error during `edit.importElements`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent an error condition caused
  /// by an analysis.reanalyze [request] that specifies an analysis root that is
  /// not in the current list of analysis roots.
  new invalidAnalysisRoot(Request request, String rootPath)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.INVALID_ANALYSIS_ROOT,
          'Invalid analysis root: $rootPath',
        ),
      );

  /// Initialize a newly created instance to represent an error condition caused
  /// by a [request] that specifies an execution context whose context root does
  /// not exist.
  new invalidExecutionContext(Request request, String contextId)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.INVALID_EXECUTION_CONTEXT,
          'Invalid execution context: $contextId',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// INVALID_FILE_PATH_FORMAT error condition.
  new invalidFilePathFormat(Request request, Object? path)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.INVALID_FILE_PATH_FORMAT,
          'Invalid file path format: $path',
        ),
      );

  /// Initialize a newly created instance to represent an error condition caused
  /// by a [request] that had invalid parameter.  [path] is the path to the
  /// invalid parameter, in JavaScript notation (e.g. "foo.bar" means that the
  /// parameter "foo" contained a key "bar" whose value was the wrong type).
  /// [expectation] is a description of the type of data that was expected.
  new invalidParameter(Request request, String path, String expectation)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.INVALID_PARAMETER,
          "Invalid parameter '$path'. $expectation.",
        ),
      );

  /// Initialize a newly created instance to represent an error condition caused
  /// by a malformed request.
  new invalidRequestFormat()
    : this(
        '',
        error: RequestError(
          RequestErrorCode.INVALID_REQUEST,
          'Invalid request',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// ORGANIZE_DIRECTIVES_ERROR error condition.
  new organizeDirectivesError(Request request, String message)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.ORGANIZE_DIRECTIVES_ERROR,
          message,
        ),
      );

  /// Initialize a newly created instance to represent the
  /// REFACTORING_REQUEST_CANCELLED error condition.
  new refactoringRequestCancelled(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.REFACTORING_REQUEST_CANCELLED,
          'The `edit.getRefactoring` request was cancelled.',
        ),
      );

  /// Initialize a newly created instance to represent the SERVER_ERROR error
  /// condition.
  factory serverError(Request request, Object? exception, Object? stackTrace) {
    var error = RequestError(
      RequestErrorCode.SERVER_ERROR,
      exception.toString(),
    );
    if (stackTrace != null) {
      error.stackTrace = stackTrace.toString();
    }
    return Response(request.id, error: error);
  }

  /// Initialize a newly created instance to represent the
  /// SORT_MEMBERS_INVALID_FILE error condition.
  new sortMembersInvalidFile(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.SORT_MEMBERS_INVALID_FILE,
          'Error during `edit.sortMembers`: invalid file.',
        ),
      );

  /// Initialize a newly created instance to represent the
  /// SORT_MEMBERS_PARSE_ERRORS error condition.
  new sortMembersParseErrors(Request request, int numErrors)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS,
          'Error during `edit.sortMembers`: file has $numErrors scan/parse errors.',
        ),
      );

  /// Initialize a newly created instance to represent an error condition caused
  /// by a [request] that cannot be handled by any known handlers.
  new unknownRequest(Request request)
    : this(
        request.id,
        error: RequestError(
          RequestErrorCode.UNKNOWN_REQUEST,
          'Unknown request',
        ),
      );

  /// Initialize a newly created instance to represent an error condition caused
  /// by a [request] for a service that is not supported.
  new unsupportedFeature(String requestId, String message)
    : this(
        requestId,
        error: RequestError(RequestErrorCode.UNSUPPORTED_FEATURE, message),
      );

  /// Return a table representing the structure of the Json object that will be
  /// sent to the client to represent this response.
  Map<String, Object> toJson() => {
    idAttributeName: id,
    errorAttributeName: ?error?.toJson(clientUriConverter: null),
    resultAttributeName: ?result,
  };

  /// Initialize a newly created instance based on the given JSON data.
  static Response? fromJson(Map<String, Object?> json) {
    try {
      var id = json[Response.idAttributeName];
      if (id is! String) {
        return null;
      }

      RequestError? decodedError;
      var error = json[Response.errorAttributeName];
      if (error is Map) {
        decodedError = RequestError.fromJson(
          ResponseDecoder(null),
          '.error',
          error,
          clientUriConverter: null,
        );
      }

      Map<String, Object?>? decodedResult;
      var result = json[Response.resultAttributeName];
      if (result is Map<String, Object?>) {
        decodedResult = result;
      }

      return Response(id, error: decodedError, result: decodedResult);
    } catch (exception) {
      return null;
    }
  }
}
