// Copyright (c) 2017, 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:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart';

/// An interface for enumerated types in the protocol.
///
/// Clients may not extend, implement or mix-in this class.
abstract class Enum {
  /// The name of the enumerated value. This should match the name of the static
  /// getter which provides access to this enumerated value.
  String get name;
}

/// A notification that can be sent to 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;
    var params = this.params;
    if (params != null) {
      jsonObject[PARAMS] = params;
    }
    return jsonObject;
  }
}

/// A request that was received from the server.
///
/// 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 server made the request.
  static const String SERVER_REQUEST_TIME = 'serverRequestTime';

  /// 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 server made the request,
  /// or `null` if this information is not provided by the server.
  final int? serverRequestTime;

  /// 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.serverRequestTime])
      : params = params ?? <String, Object>{};

  /// 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).
  factory Request.fromJson(Map<String, Object> result) {
    var id = result[Request.ID];
    var method = result[Request.METHOD];
    if (id is! String || method is! String) {
      throw StateError('Unexpected type for id or method');
    }
    var time = result[Request.SERVER_REQUEST_TIME];
    if (time != null && time is! int) {
      throw StateError('Unexpected type for server request time');
    }
    var params = result[Request.PARAMS];
    if (params is Map || params == null) {
      return Request(id, method, params as Map<String, Object>?, time as int?);
    } else {
      throw StateError('Unexpected type for params');
    }
  }

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

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

  /// Return a table representing the structure of the Json object that will be
  /// sent to the server to represent this response.
  Map<String, Object> toJson() {
    var jsonObject = <String, Object>{};
    jsonObject[ID] = id;
    jsonObject[METHOD] = method;
    if (params.isNotEmpty) {
      jsonObject[PARAMS] = params;
    }
    var serverRequestTime = this.serverRequestTime;
    if (serverRequestTime != null) {
      jsonObject[SERVER_REQUEST_TIME] = serverRequestTime;
    }
    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;
  }
}

/// A collection of utility methods that create instances of the generated class
/// [RequestError].
///
/// Clients may not extend, implement or mix-in this class.
class RequestErrorFactory {
  /// Return a request error representing an error condition caused by a
  /// [request] that had an invalid edit object.
  static RequestError invalidOverlayChangeInvalidEdit() => RequestError(
      RequestErrorCode.INVALID_OVERLAY_CHANGE,
      'Invalid overlay change: invalid edit');

  /// Return a request error representing an error condition caused by a
  /// [request] that attempted to change an existing overlay when no overlay
  /// existed.
  static RequestError invalidOverlayChangeNoContent() => RequestError(
      RequestErrorCode.INVALID_OVERLAY_CHANGE,
      'Invalid overlay change: no content to change');

  /// Return a request error representing an error condition caused by a request
  /// that had an invalid parameter. The [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). The
  /// [expectation] is a description of the type of data that was expected.
  static RequestError invalidParameter(String path, String expectation) =>
      RequestError(RequestErrorCode.INVALID_PARAMETER,
          "Invalid parameter '$path'. $expectation.");

  /// Return a request error representing an error that occurred in the plugin.
  static RequestError pluginError(dynamic exception, String? stackTrace) =>
      RequestError(RequestErrorCode.PLUGIN_ERROR, exception.toString(),
          stackTrace: stackTrace);

  /// Return a request error representing an error condition caused by a request
  /// with the given [method] that cannot be handled by any known handlers.
  static RequestError unknownRequest(String method) => RequestError(
      RequestErrorCode.UNKNOWN_REQUEST, 'Unknown request: $method');
}

/// An exception that occurred during the handling of a request that requires
/// that an error be returned to the server.
///
/// Clients may not extend, implement or mix-in this class.
class RequestFailure implements Exception {
  /// A description of the error that was encountered.
  final RequestError error;

  /// Initialize a newly created exception to return a response with the given
  /// [error].
  RequestFailure(this.error);
}

/// A response to the server.
///
/// Clients may not extend, implement or mix-in this class.
class 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 time at which the request was
  /// handled by the plugin.
  static const String REQUEST_TIME = 'requestTime';

  /// 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;

  /// The time at which the request was handled by the plugin.
  final int requestTime;

  /// 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.requestTime, {this.error, Map<String, Object>? result})
      : result = result;

  /// Initialize a newly created instance based on the given JSON data.
  factory Response.fromJson(Map json) {
    var id = json[ID];
    if (id is! String) {
      throw StateError('Unexpected type for id');
    }
    var error = json[ERROR];
    RequestError? decodedError;
    if (error is Map) {
      decodedError =
          RequestError.fromJson(ResponseDecoder(null), '.error', error);
    }
    var requestTime = json[REQUEST_TIME];
    if (requestTime is! int) {
      throw StateError('Unexpected type for requestTime');
    }
    var result = json[RESULT];
    Map<String, Object>? decodedResult;
    if (result is Map) {
      decodedResult = result as Map<String, Object>;
    }
    return Response(id, requestTime,
        error: decodedError, result: decodedResult);
  }

  /// 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;
    var error = this.error;
    if (error != null) {
      jsonObject[ERROR] = error.toJson();
    }
    jsonObject[REQUEST_TIME] = requestTime;
    var result = this.result;
    if (result != null) {
      jsonObject[RESULT] = result;
    }
    return jsonObject;
  }
}
