// 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.
import 'dart:convert' hide JsonDecoder;

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

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

/// A notification that can be sent from the server about an event that
/// occurred.
///
/// Clients may not extend, implement or mix-in this class.
class Notification {
  /// The name of the JSON attribute containing the name of the event that
  /// triggered the notification.
  static const String EVENT = 'event';

  /// The name of the JSON attribute containing the result values.
  static const String PARAMS = '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.
  Notification(this.event, [this.params]);

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

  /// 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() {
    var jsonObject = <String, Object>{};
    jsonObject[EVENT] = event;
    final params = this.params;
    if (params != null) {
      jsonObject[PARAMS] = params;
    }
    return jsonObject;
  }
}

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

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

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

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

  /// The unique identifier used to identify this request.
  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.
  Request(this.id, this.method,
      [Map<String, Object?>? params, this.clientRequestTime])
      : params = params ?? <String, Object?>{};

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

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

  /// 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() {
    var jsonObject = <String, Object>{};
    jsonObject[ID] = id;
    jsonObject[METHOD] = method;
    if (params.isNotEmpty) {
      jsonObject[PARAMS] = params;
    }
    final clientRequestTime = this.clientRequestTime;
    if (clientRequestTime != null) {
      jsonObject[CLIENT_REQUEST_TIME] = clientRequestTime;
    }
    return jsonObject;
  }

  bool _equalLists(List? first, List? second) {
    if (first == null) {
      return second == null;
    }
    if (second == null) {
      return false;
    }
    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? first, Map? second) {
    if (first == null) {
      return second == null;
    }
    if (second == null) {
      return false;
    }
    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;
  }

  /// Return a request parsed from the given json, 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': {
  ///       paramter_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.ID];
    var method = result[Request.METHOD];
    if (id is! String || method is! String) {
      return null;
    }
    var time = result[Request.CLIENT_REQUEST_TIME];
    if (time is! int?) {
      return null;
    }
    var params = result[Request.PARAMS];
    if (params is Map<String, Object?>?) {
      return Request(id, method, params, time);
    } else {
      return null;
    }
  }

  /// Return a request parsed from the given [data], 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': {
  ///       paramter_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? fromString(String data) {
    try {
      var result = json.decode(data);
      if (result is Map<String, Object?>) {
        return Request.fromJson(result);
      }
      return null;
    } catch (exception) {
      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 reponse.
  RequestFailure(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 response to a request.
///
/// Clients may not extend, implement or mix-in this class.
class Response {
  /// The [Response] instance that is returned when a real [Response] cannot
  /// be provided at the moment.
  static final Response DELAYED_RESPONSE = Response('DELAYED_RESPONSE');

  /// The name of the JSON attribute containing the id of the request for which
  /// this is a response.
  static const String ID = 'id';

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

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

  /// The unique identifier used to identify the request that this response is
  /// associated with.
  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.
  Response(this.id, {this.result, this.error});

  /// Initialize a newly created instance to represent the CONTENT_MODIFIED
  /// error condition.
  Response.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.
  Response.debugPortCouldNotBeOpened(Request request, dynamic 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.
  Response.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.
  Response.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.
  Response.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.
  Response.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.
  Response.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.
  Response.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_KYTHE_ENTRIES_INVALID_FILE error condition.
  Response.getKytheEntriesInvalidFile(Request request)
      : this(request.id,
            error: RequestError(RequestErrorCode.GET_KYTHE_ENTRIES_INVALID_FILE,
                'Error during `analysis.getKytheEntries`: invalid file.'));

  /// Initialize a newly created instance to represent the
  /// GET_NAVIGATION_INVALID_FILE error condition.
  Response.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.
  Response.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.
  Response.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.
  Response.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.
  Response.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.
  Response.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.
  Response.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.
  Response.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.
  Response.invalidFilePathFormat(Request request, 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.
  Response.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.
  Response.invalidRequestFormat()
      : this('',
            error: RequestError(
                RequestErrorCode.INVALID_REQUEST, 'Invalid request'));

  /// Initialize a newly created instance to represent the
  /// ORGANIZE_DIRECTIVES_ERROR error condition.
  Response.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.
  Response.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 Response.serverError(Request request, exception, 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.
  Response.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.
  Response.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.
  Response.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.
  Response.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() {
    var jsonObject = <String, Object>{};
    jsonObject[ID] = id;
    final error = this.error;
    if (error != null) {
      jsonObject[ERROR] = error.toJson();
    }
    final result = this.result;
    if (result != null) {
      jsonObject[RESULT] = result;
    }
    return jsonObject;
  }

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

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

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

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