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

library protocol;

import 'dart:collection';
import 'dart:convert' show JsonDecoder;

/**
 * An abstract enumeration.
 */
abstract class Enum2<E extends Enum2> implements Comparable<E> {
  /**
   * The name of this enum constant, as declared in the enum declaration.
   */
  final String name;

  /**
   * The position in the enum declaration.
   */
  final int ordinal;

  const Enum2(this.name, this.ordinal);

  @override
  int get hashCode => ordinal;

  @override
  String toString() => name;

  int compareTo(E other) => ordinal - other.ordinal;

  /**
   * Returns the enum constant with the given [name], `null` if not found.
   */
  static Enum2 valueOf(List<Enum2> values, String name) {
    for (int i = 0; i < values.length; i++) {
      Enum2 value = values[i];
      if (value.name == name) {
        return value;
      }
    }
    return null;
  }
}


/**
 * Instances of the class [Request] represent a request that was received.
 */
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 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 = new HashMap<String, Object>();

  /**
   * A decoder that can be used to decode strings into JSON objects.
   */
  static const JsonDecoder DECODER = const JsonDecoder(null);

  /**
   * Initialize a newly created [Request] to have the given [id] and [method]
   * name.
   */
  Request(this.id, this.method);

  /**
   * 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:
   *
   *   {
   *     'id': String,
   *     'method': methodName,
   *     'params': {
   *       paramter_name: value
   *     }
   *   }
   *
   * where the parameters are optional and can contain any number of name/value
   * pairs.
   */
  factory Request.fromString(String data) {
    try {
      var result = DECODER.convert(data);
      if (result is! Map) {
        return null;
      }
      var id = result[Request.ID];
      var method = result[Request.METHOD];
      if (id is! String || method is! String) {
        return null;
      }
      var params = result[Request.PARAMS];
      Request request = new Request(id, method);
      if (params is Map) {
        params.forEach((String key, Object value) {
          request.setParameter(key, value);
        });
      } else if (params != null) {
        return null;
      }
      return request;
    } catch (exception) {
      return null;
    }
  }

  /**
   * Return the value of the parameter with the given [name], or [defaultValue]
   * if there is no such parameter associated with this request.
   */
  RequestDatum getParameter(String name, defaultValue) {
    Object value = params[name];
    if (value == null) {
      return new RequestDatum(this, "default for $name", defaultValue);
    }
    return new RequestDatum(this, name, params[name]);
  }

  /**
   * Return the value of the parameter with the given [name], or throw a
   * [RequestFailure] exception with an appropriate error message if there is no
   * such parameter associated with this request.
   */
  RequestDatum getRequiredParameter(String name) {
    Object value = params[name];
    if (value == null) {
      throw new RequestFailure(new Response.missingRequiredParameter(this, name));
    }
    return new RequestDatum(this, name, value);
  }

  /**
   * Set the value of the parameter with the given [name] to the given [value].
   */
  void setParameter(String name, Object value) {
    params[name] = value;
  }

  /**
   * 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 = new Map<String, Object>();
    jsonObject[ID] = id;
    jsonObject[METHOD] = method;
    if (params.isNotEmpty) {
      jsonObject[PARAMS] = params;
    }
    return jsonObject;
  }
}

/**
 * Instances of the class [RequestDatum] wrap a piece of data from a
 * request parameter, and contain accessor methods which automatically validate
 * and convert the data into the appropriate form.
 */
class RequestDatum {
  /**
   * Request object that should be referred to in any errors that are
   * generated.
   */
  final Request request;

  /**
   * String description of how [datum] was obtained from the request.
   */
  final String path;

  /**
   * Value to be decoded and validated.
   */
  final dynamic datum;

  /**
   * Create a RequestDatum for decoding and validating [datum], which refers to
   * [request] in any errors it reports.
   */
  RequestDatum(this.request, this.path, this.datum);

  /**
   * Validate that the datum is a Map containing the given [key], and return
   * a [RequestDatum] containing the corresponding value.
   */
  RequestDatum operator [](String key) {
    if (datum is! Map) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "be a map"));
    }
    if (!datum.containsKey(key)) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "contain key '$key'"));
    }
    return new RequestDatum(request, "$path.$key", datum[key]);
  }

  /**
   * Return `true` if the datum is a Map containing the given [key].
   */
  bool hasKey(String key) {
    if (datum is! Map) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "be a map"));
    }
    return datum.containsKey(key);
  }

  /**
   * Validate that the datum is a Map whose keys are strings, and call [f] on
   * each key/value pair in the map.
   */
  void forEachMap(void f(String key, RequestDatum value)) {
    if (datum is! Map) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "be a map"));
    }
    datum.forEach((String key, value) {
      f(key, new RequestDatum(request, "$path.$key", value));
    });
  }

  /**
   * Validate that the datum is an integer (or a string that can be parsed
   * as an integer), and return the int.
   */
  int asInt() {
    if (datum is int) {
      return datum;
    } else if (datum is String) {
      return int.parse(datum, onError: (String value) {
        throw new RequestFailure(new Response.invalidParameter(request, path,
            "be an integer"));
      });
    }
    throw new RequestFailure(new Response.invalidParameter(request, path,
        "be an integer"));
  }

  /**
   * Validate that the datum is a boolean (or a string that can be parsed
   * as a boolean), and return the bool.
   *
   * The value is typically the result of invoking either [getParameter] or
   * [getRequiredParameter].
   */
  bool asBool() {
    if (datum is bool) {
      return datum;
    } else if (datum == 'true') {
      return true;
    } else if (datum == 'false') {
      return false;
    }
    throw new RequestFailure(new Response.invalidParameter(request, datum,
        "be a boolean"));
  }

  /**
   * Validate that the datum is a string, and return it.
   */
  String asString() {
    if (datum is! String) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "be a string"));
    }
    return datum;
  }

  /**
   * Determine if the datum is a list of strings.
   */
  bool get isStringList {
    if (datum is! List) {
      return false;
    }
    for (var element in datum) {
      if (element is! String) {
        return false;
      }
    }
    return true;
  }

  /**
   * Validate that the datum is a list of strings, and return it.
   */
  List<String> asStringList() {
    if (!isStringList) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "be a list of strings"));
    }
    return datum;
  }

  /**
   * Validate that the datum is a list of strings, and convert it into [Enum]s.
   */
  Set<Enum2> asEnumSet(List<Enum2> allValues) {
    Set values = new Set();
    for (String name in asStringList()) {
      Enum2 value = Enum2.valueOf(allValues, name);
      if (value == null) {
        throw new RequestFailure(new Response.invalidParameter(request, path,
            "be a list of names from the list $allValues"));
      }
      values.add(value);
    }
    return values;
  }

  /**
   * Determine if the datum is a map whose values are all strings.
   *
   * Note: we can safely assume that the keys are all strings, since JSON maps
   * cannot have any other key type.
   */
  bool get isStringMap {
    if (datum is! Map) {
      return false;
    }
    for (var value in datum.values) {
      if (value is! String) {
        return false;
      }
    }
    return true;
  }

  /**
   * Validate that the datum is a map from strings to strings, and return it.
   */
  Map<String, String> asStringMap() {
    if (!isStringMap) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "be a string map"));
    }
    return datum;
  }

  /**
   * Determine if the datum is a map whose values are all string lists.
   *
   * Note: we can safely assume that the keys are all strings, since JSON maps
   * cannot have any other key type.
   */
  bool isStringListMap() {
    if (datum is! Map) {
      return false;
    }
    for (var value in datum.values) {
      if (value is! List) {
        return false;
      }
      for (var listItem in value) {
        if (listItem is! String) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * Validate that the datum is a map from strings to string listss, and return
   * it.
   */
  Map<String, List<String>> asStringListMap() {
    if (!isStringListMap()) {
      throw new RequestFailure(new Response.invalidParameter(request, path,
          "be a string list map"));
    }
    return datum;
  }
}

/**
 * Instances of the class [Response] represent a response to a request.
 */
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 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. The table
   * should be empty if there was an error.
   */
  final Map<String, Object> result = new HashMap<String, Object>();

  /**
   * Initialize a newly created instance to represent a response to a request
   * with the given [id]. If an [error] is provided then the response will
   * represent an error condition.
   */
  Response(this.id, [this.error]);

  /**
   * Initialize a newly created instance to represent an error condition caused
   * by a [request] referencing a context that does not exist.
   */
  Response.contextDoesNotExist(Request request)
    : this(request.id, new RequestError(-1, 'Context does not exist'));

  /**
   * 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, new RequestError(-2,
          "Expected parameter $path to $expectation"));

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

  /**
   * Initialize a newly created instance to represent an error condition caused
   * by a [request] that does not have a required parameter.
   */
  Response.missingRequiredParameter(Request request, String parameterName)
    : this(request.id, new RequestError(-5, 'Missing required parameter: $parameterName'));

  /**
   * Initialize a newly created instance to represent an error condition caused
   * by a [request] that takes a set of analysis options but for which an
   * unknown analysis option was provided.
   */
  Response.unknownAnalysisOption(Request request, String optionName)
    : this(request.id, new RequestError(-6, 'Unknown analysis option: "$optionName"'));

  /**
   * 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, new RequestError(-7, 'Unknown request'));

  Response.contextAlreadyExists(Request request)
    : this(request.id, new RequestError(-8, 'Context already exists'));

  Response.unsupportedFeature(String requestId, String message)
    : this(requestId, new RequestError(-9, message));

  /**
   * Initialize a newly created instance to represent an error condition caused
   * by a `analysis.setSubscriptions` [request] that includes an unknown
   * analysis service name.
   */
  Response.unknownAnalysisService(Request request, String name)
    : this(request.id, new RequestError(-10, 'Unknown analysis service: "$name"'));

  /**
   * Initialize a newly created instance based upon the given JSON data
   */
  factory Response.fromJson(Map<String, Object> json) {
    try {
      Object id = json[Response.ID];
      if (id is! String) {
        return null;
      }
      Object error = json[Response.ERROR];
      Object result = json[Response.RESULT];
      Response response;
      if (error is Map) {
        response = new Response(id, new RequestError.fromJson(error));
      } else {
        response = new Response(id);
      }
      if (result is Map) {
        result.forEach((String key, Object value) {
          response.setResult(key, value);
        });
      }
      return response;
    } catch (exception) {
      return null;
    }
  }

  /**
   * Return the value of the result field with the given [name].
   */
  Object getResult(String name) {
    return result[name];
  }

  /**
   * Set the value of the result field with the given [name] to the given [value].
   */
  void setResult(String name, Object value) {
    result[name] = value;
  }

  /**
   * 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 = new Map<String, Object>();
    jsonObject[ID] = id;
    if (error != null) {
      jsonObject[ERROR] = error.toJson();
    }
    if (!result.isEmpty) {
      jsonObject[RESULT] = result;
    }
    return jsonObject;
  }
}

/**
 * Instances of the class [RequestError] represent information about an error
 * that occurred while attempting to respond to a [Request].
 */
class RequestError {
  /**
   * The name of the JSON attribute containing the code that uniquely identifies
   * the error that occurred.
   */
  static const String CODE = 'code';

  /**
   * The name of the JSON attribute containing an object with additional data
   * related to the error.
   */
  static const String DATA = 'data';

  /**
   * The name of the JSON attribute containing a short description of the error.
   */
  static const String MESSAGE = 'message';

  /**
   * An error code indicating a parse error. Invalid JSON was received by the
   * server. An error occurred on the server while parsing the JSON text.
   */
  static const int CODE_PARSE_ERROR = -32700;

  /**
   * An error code indicating that the analysis server has already been
   * started (and hence won't accept new connections).
   */
  static const int CODE_SERVER_ALREADY_STARTED = -32701;

  /**
   * An error code indicating an invalid request. The JSON sent is not a valid
   * [Request] object.
   */
  static const int CODE_INVALID_REQUEST = -32600;

  /**
   * An error code indicating a method not found. The method does not exist or
   * is not currently available.
   */
  static const int CODE_METHOD_NOT_FOUND = -32601;

  /**
   * An error code indicating one or more invalid parameters.
   */
  static const int CODE_INVALID_PARAMS = -32602;

  /**
   * An error code indicating an internal error.
   */
  static const int CODE_INTERNAL_ERROR = -32603;

  /**
   * An error code indicating a problem using the specified Dart SDK.
   */
  static const int CODE_SDK_ERROR = -32603;

  /*
   * In addition, codes -32000 to -32099 indicate a server error. They are
   * reserved for implementation-defined server-errors.
   */

  /**
   * The code that uniquely identifies the error that occurred.
   */
  final int code;

  /**
   * A short description of the error.
   */
  final String message;

  /**
   * A table mapping the names of notification parameters to their values.
   */
  final Map<String, Object> data = new HashMap<String, Object>();

  /**
   * Initialize a newly created [Error] to have the given [code] and [message].
   */
  RequestError(this.code, this.message);

  /**
   * Initialize a newly created [Error] to indicate a parse error. Invalid JSON
   * was received by the server. An error occurred on the server while parsing
   * the JSON text.
   */
  RequestError.parseError() : this(CODE_PARSE_ERROR, "Parse error");

  /**
   * Initialize a newly created [Error] to indicate that the analysis server
   * has already been started (and hence won't accept new connections).
   */
  RequestError.serverAlreadyStarted()
    : this(CODE_SERVER_ALREADY_STARTED, "Server already started");

  /**
   * Initialize a newly created [Error] to indicate an invalid request. The
   * JSON sent is not a valid [Request] object.
   */
  RequestError.invalidRequest() : this(CODE_INVALID_REQUEST, "Invalid request");

  /**
   * Initialize a newly created [Error] to indicate that a method was not found.
   * Either the method does not exist or is not currently available.
   */
  RequestError.methodNotFound() : this(CODE_METHOD_NOT_FOUND, "Method not found");

  /**
   * Initialize a newly created [Error] to indicate one or more invalid
   * parameters.
   */
  RequestError.invalidParameters() : this(CODE_INVALID_PARAMS, "Invalid parameters");

  /**
   * Initialize a newly created [Error] to indicate an internal error.
   */
  RequestError.internalError() : this(CODE_INTERNAL_ERROR, "Internal error");

  /**
   * Initialize a newly created [Error] from the given JSON.
   */
  factory RequestError.fromJson(Map<String, Object> json) {
    try {
      int code = json[RequestError.CODE];
      String message = json[RequestError.MESSAGE];
      Map<String, Object> data = json[RequestError.DATA];
      RequestError requestError = new RequestError(code, message);
      if (data != null) {
        data.forEach((String key, Object value) {
          requestError.setData(key, value);
        });
      }
      return requestError;
    } catch (exception) {
      return null;
    }
  }

  /**
   * Return the value of the data with the given [name], or `null` if there is
   * no such data associated with this error.
   */
  Object getData(String name) => data[name];

  /**
   * Set the value of the data with the given [name] to the given [value].
   */
  void setData(String name, Object value) {
    data[name] = value;
  }

  /**
   * 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 = new Map<String, Object>();
    jsonObject[CODE] = code;
    jsonObject[MESSAGE] = message;
    if (!data.isEmpty) {
      jsonObject[DATA] = data;
    }
    return jsonObject;
  }

  @override
  String toString() => toJson().toString();
}

/**
 * Instances of the class [Notification] represent a notification from the
 * server about an event that occurred.
 */
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.
   */
  final Map<String, Object> params = new HashMap<String, Object>();

  /**
   * Initialize a newly created [Notification] to have the given [event] name.
   */
  Notification(this.event);

  /**
   * Initialize a newly created instance based upon the given JSON data
   */
  factory Notification.fromJson(Map<String, Object> json) {
    try {
      String event = json[Notification.EVENT];
      Object params = json[Notification.PARAMS];
      Notification notification = new Notification(event);
      if (params is Map) {
        params.forEach((String key, Object value) {
          notification.setParameter(key, value);
        });
      }
      return notification;
    } catch (exception) {
      return null;
    }
  }

  /**
   * Return the value of the parameter with the given [name], or `null` if there
   * is no such parameter associated with this notification.
   */
  Object getParameter(String name) => params[name];

  /**
   * Set the value of the parameter with the given [name] to the given [value].
   */
  void setParameter(String name, Object value) {
    params[name] = value;
  }

  /**
   * 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 = new Map<String, Object>();
    jsonObject[EVENT] = event;
    if (!params.isEmpty) {
      jsonObject[PARAMS] = params;
    }
    return jsonObject;
  }
}

/**
 * Instances of the class [RequestHandler] implement a handler that can handle
 * requests and produce responses for them.
 */
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);
}

/**
 * Instances of the class [RequestFailure] represent an exception that occurred
 * during the handling of a request that requires that an error be returned to
 * the client.
 */
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);
}
