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

import 'dart:async';
import 'dart:convert';

import 'package:analysis_server/plugin/protocol/protocol.dart';

/**
 * Instances of the class [ChannelChunkSink] uses a [Converter] to translate
 * chunks.
 */
class ChannelChunkSink<S, T> extends ChunkedConversionSink<S> {
  /**
   * The converter used to translate chunks.
   */
  final Converter<S, T> converter;

  /**
   * The sink to which the converted chunks are added.
   */
  final Sink sink;

  /**
   * A flag indicating whether the sink has been closed.
   */
  bool closed = false;

  /**
   * Initialize a newly create sink to use the given [converter] to convert
   * chunks before adding them to the given [sink].
   */
  ChannelChunkSink(this.converter, this.sink);

  @override
  void add(S chunk) {
    if (!closed) {
      T convertedChunk = converter.convert(chunk);
      if (convertedChunk != null) {
        sink.add(convertedChunk);
      }
    }
  }

  @override
  void close() {
    closed = true;
    sink.close();
  }
}

/**
 * The abstract class [ClientCommunicationChannel] defines the behavior of
 * objects that allow a client to send [Request]s to an [AnalysisServer] and to
 * receive both [Response]s and [Notification]s.
 */
abstract class ClientCommunicationChannel {
  /**
   * The stream of notifications from the server.
   */
  Stream<Notification> notificationStream;

  /**
   * The stream of responses from the server.
   */
  Stream<Response> responseStream;

  /**
   * Close the channel to the server. Once called, all future communication
   * with the server via [sendRequest] will silently be ignored.
   */
  Future close();

  /**
   * Send the given [request] to the server
   * and return a future with the associated [Response].
   */
  Future<Response> sendRequest(Request request);
}

/**
 * Instances of the class [JsonStreamDecoder] convert JSON strings to JSON
 * maps.
 */
class JsonStreamDecoder extends Converter<String, Map> {
  @override
  Map convert(String text) => JSON.decode(text);

  @override
  ChunkedConversionSink startChunkedConversion(Sink sink) =>
      new ChannelChunkSink<String, Map>(this, sink);
}

/**
 * Instances of the class [NotificationConverter] convert JSON maps to
 * [Notification]s.
 */
class NotificationConverter extends Converter<Map, Notification> {
  @override
  Notification convert(Map json) => new Notification.fromJson(json);

  @override
  ChunkedConversionSink startChunkedConversion(Sink sink) =>
      new ChannelChunkSink<Map, Notification>(this, sink);
}

/**
 * Instances of the class [ResponseConverter] convert JSON maps to [Response]s.
 */
class ResponseConverter extends Converter<Map, Response> {
  @override
  Response convert(Map json) => new Response.fromJson(json);

  @override
  ChunkedConversionSink startChunkedConversion(Sink sink) =>
      new ChannelChunkSink<Map, Response>(this, sink);
}

/**
 * The abstract class [ServerCommunicationChannel] defines the behavior of
 * objects that allow an [AnalysisServer] to receive [Request]s and to return
 * both [Response]s and [Notification]s.
 */
abstract class ServerCommunicationChannel {
  /**
   * Close the communication channel.
   */
  void close();

  /**
   * Listen to the channel for requests. If a request is received, invoke the
   * [onRequest] function. If an error is encountered while trying to read from
   * the socket, invoke the [onError] function. If the socket is closed by the
   * client, invoke the [onDone] function.
   * Only one listener is allowed per channel.
   */
  void listen(void onRequest(Request request),
      {Function onError, void onDone()});

  /**
   * Send the given [notification] to the client.
   */
  void sendNotification(Notification notification);

  /**
   * Send the given [response] to the client.
   */
  void sendResponse(Response response);
}
