// 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
    ChunkedConverter<String, Map, String, Map> {
  @override
  Map convert(String text) => JSON.decode(text);

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

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

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

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

  @override
  ChunkedConversionSink<Map> startChunkedConversion(Sink<Response> 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);
}
