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

import 'dart:convert';

import 'package:analysis_server/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) {
      var 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<String> startChunkedConversion(Sink<Map> sink) =>
      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) => Notification.fromJson(json);

  @override
  ChunkedConversionSink<Map> startChunkedConversion(Sink<Notification> sink) =>
      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) => Response.fromJson(json);

  @override
  ChunkedConversionSink<Map> startChunkedConversion(Sink<Response> sink) =>
      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 Function(Request request) onRequest,
      {Function onError, void Function() onDone});

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

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