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

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 new Notification(json[Notification.EVENT],
        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() {
    Map<String, Object> jsonObject = {};
    jsonObject[EVENT] = event;
    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>{};

  /**
   * 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) {
      return null;
    }
    var time = result[Request.CLIENT_REQUEST_TIME];
    if (time != null && time is! int) {
      return null;
    }
    var params = result[Request.PARAMS];
    if (params is Map || params == null) {
      return new Request(id, method, params as Map<String, Object>, 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).
   */
  factory Request.fromString(String data) {
    try {
      var result = json.decode(data);
      if (result is Map) {
        return new Request.fromJson(result as Map<String, dynamic>);
      }
      return null;
    } catch (exception) {
      return null;
    }
  }

  @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() {
    Map<String, Object> jsonObject = <String, Object>{};
    jsonObject[ID] = id;
    jsonObject[METHOD] = method;
    if (params.isNotEmpty) {
      jsonObject[PARAMS] = params;
    }
    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;
    }
    int length = first.length;
    if (length != second.length) {
      return false;
    }
    for (int 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;
  }
}

/**
 * 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);
}

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

  /**
   * Create and return the `DEBUG_PORT_COULD_NOT_BE_OPENED` error response.
   */
  Response.debugPortCouldNotBeOpened(Request request, dynamic error)
      : this(request.id,
            error: new 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: new 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: new 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: new RequestError(RequestErrorCode.FORMAT_WITH_ERRORS,
                'Error during `edit.format`: source contains syntax errors.'));

  /**
   * Initialize a newly created instance based on the given JSON data.
   */
  factory Response.fromJson(Map json) {
    try {
      Object id = json[Response.ID];
      if (id is! String) {
        return null;
      }
      Object error = json[Response.ERROR];
      RequestError decodedError;
      if (error is Map) {
        decodedError = new RequestError.fromJson(
            new ResponseDecoder(null), '.error', error);
      }
      Object result = json[Response.RESULT];
      Map<String, Object> decodedResult;
      if (result is Map) {
        decodedResult = result as Map<String, Object>;
      }
      return new Response(id, error: decodedError, result: decodedResult);
    } catch (exception) {
      return null;
    }
  }

  /**
   * Initialize a newly created instance to represent the
   * GET_ERRORS_INVALID_FILE error condition.
   */
  Response.getErrorsInvalidFile(Request request)
      : this(request.id,
            error: new RequestError(RequestErrorCode.GET_ERRORS_INVALID_FILE,
                'Error during `analysis.getErrors`: 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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: new 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) {
    RequestError error =
        new RequestError(RequestErrorCode.SERVER_ERROR, exception.toString());
    if (stackTrace != null) {
      error.stackTrace = stackTrace.toString();
    }
    return new 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: new 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: new 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: new 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: new 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() {
    Map<String, Object> jsonObject = <String, Object>{};
    jsonObject[ID] = id;
    if (error != null) {
      jsonObject[ERROR] = error.toJson();
    }
    if (result != null) {
      jsonObject[RESULT] = result;
    }
    return jsonObject;
  }
}
