// Copyright (c) 2012, 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.

part of dart.io;

/**
 * The [SecureServerSocket] is a server socket, providing a stream of high-level
 * [Socket]s.
 *
 * See [SecureSocket] for more info.
 */
class SecureServerSocket extends Stream<SecureSocket> implements ServerSocket {
  final RawSecureServerSocket _socket;

  SecureServerSocket._(RawSecureServerSocket this._socket);

  /**
   * Returns a future for a [SecureServerSocket]. When the future
   * completes the server socket is bound to the given [address] and
   * [port] and has started listening on it.
   *
   * The [address] can either be a [String] or an
   * [InternetAddress]. If [address] is a [String], [bind] will
   * perform a [InternetAddress.lookup] and use the first value in the
   * list. To listen on the loopback adapter, which will allow only
   * incoming connections from the local host, use the value
   * [InternetAddress.LOOPBACK_IP_V4] or
   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
   * connection from the network use either one of the values
   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
   * bind to all interfaces or the IP address of a specific interface.
   *
   * If [port] has the value [:0:] an ephemeral port will be chosen by
   * the system. The actual port used can be retrieved using the
   * [port] getter.
   *
   * The optional argument [backlog] can be used to specify the listen
   * backlog for the underlying OS listen setup. If [backlog] has the
   * value of [:0:] (the default) a reasonable value will be chosen by
   * the system.
   *
   * Incoming client connections are promoted to secure connections, using
   * the server certificate given by [certificateName].
   *
   * [address] must be given as a numeric address, not a host name.
   *
   * [certificateName] is the nickname or the distinguished name (DN) of
   * the certificate in the certificate database. It is looked up in the
   * NSS certificate database set by SecureSocket.setCertificateDatabase.
   * If [certificateName] contains "CN=", it is assumed to be a distinguished
   * name.  Otherwise, it is looked up as a nickname.
   *
   * To request or require that clients authenticate by providing an SSL (TLS)
   * client certificate, set the optional parameter [requestClientCertificate]
   * or [requireClientCertificate] to true.  Requiring a certificate implies
   * requesting a certificate, so one doesn't need to set both to true.
   * To check whether a client certificate was received, check
   * SecureSocket.peerCertificate after connecting.  If no certificate
   * was received, the result will be null.
   */
  static Future<SecureServerSocket> bind(
      address,
      int port,
      String certificateName,
      {int backlog: 0,
       bool v6Only: false,
       bool requestClientCertificate: false,
       bool requireClientCertificate: false}) {
    return RawSecureServerSocket.bind(
        address,
        port,
        certificateName,
        backlog: backlog,
        v6Only: v6Only,
        requestClientCertificate: requestClientCertificate,
        requireClientCertificate: requireClientCertificate).then(
            (serverSocket) => new SecureServerSocket._(serverSocket));
  }

  StreamSubscription<SecureSocket> listen(void onData(SecureSocket socket),
                                          {void onError(error),
                                           void onDone(),
                                           bool cancelOnError}) {
    return _socket.map((rawSocket) => new SecureSocket._(rawSocket))
                  .listen(onData,
                          onError: onError,
                          onDone: onDone,
                          cancelOnError: cancelOnError);
  }

  /**
   * Returns the port used by this socket.
   */
  int get port => _socket.port;

  /**
   * Closes the socket. The returned future completes when the socket
   * is fully closed and is no longer bound.
   */
  Future<SecureServerSocket> close() => _socket.close().then((_) => this);
}


/**
 * The RawSecureServerSocket is a server socket, providing a stream of low-level
 * [RawSecureSocket]s.
 *
 * See [RawSecureSocket] for more info.
 */
class RawSecureServerSocket extends Stream<RawSecureSocket> {
  RawServerSocket _socket;
  StreamController<RawSecureSocket> _controller;
  StreamSubscription<RawSocket> _subscription;
  final String certificateName;
  final bool requestClientCertificate;
  final bool requireClientCertificate;
  bool _closed = false;

  RawSecureServerSocket._(RawServerSocket serverSocket,
                          String this.certificateName,
                          bool this.requestClientCertificate,
                          bool this.requireClientCertificate) {
    _socket = serverSocket;
    _controller = new StreamController<RawSecureSocket>(
        sync: true,
        onListen: _onSubscriptionStateChange,
        onPause: _onPauseStateChange,
        onResume: _onPauseStateChange,
        onCancel: _onSubscriptionStateChange);
  }

  /**
   * Returns a future for a [RawSecureServerSocket]. When the future
   * completes the server socket is bound to the given [address] and
   * [port] and has started listening on it.
   *
   * The [address] can either be a [String] or an
   * [InternetAddress]. If [address] is a [String], [bind] will
   * perform a [InternetAddress.lookup] and use the first value in the
   * list. To listen on the loopback adapter, which will allow only
   * incoming connections from the local host, use the value
   * [InternetAddress.LOOPBACK_IP_V4] or
   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
   * connection from the network use either one of the values
   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
   * bind to all interfaces or the IP address of a specific interface.
   *
   * If [port] has the value [:0:] an ephemeral port will be chosen by
   * the system. The actual port used can be retrieved using the
   * [port] getter.
   *
   * The optional argument [backlog] can be used to specify the listen
   * backlog for the underlying OS listen setup. If [backlog] has the
   * value of [:0:] (the default) a reasonable value will be chosen by
   * the system.
   *
   * Incoming client connections are promoted to secure connections,
   * using the server certificate given by [certificateName].
   *
   * [address] must be given as a numeric address, not a host name.
   *
   * [certificateName] is the nickname or the distinguished name (DN) of
   * the certificate in the certificate database. It is looked up in the
   * NSS certificate database set by SecureSocket.setCertificateDatabase.
   * If [certificateName] contains "CN=", it is assumed to be a distinguished
   * name.  Otherwise, it is looked up as a nickname.
   *
   * To request or require that clients authenticate by providing an SSL (TLS)
   * client certificate, set the optional parameters requestClientCertificate or
   * requireClientCertificate to true.  Require implies request, so one doesn't
   * need to specify both.  To check whether a client certificate was received,
   * check SecureSocket.peerCertificate after connecting.  If no certificate
   * was received, the result will be null.
   */
  static Future<RawSecureServerSocket> bind(
      String address,
      int port,
      String certificateName,
      {int backlog: 0,
       bool v6Only: false,
       bool requestClientCertificate: false,
       bool requireClientCertificate: false}) {
    return RawServerSocket.bind(address, port, backlog: backlog, v6Only: v6Only)
        .then((serverSocket) => new RawSecureServerSocket._(
            serverSocket,
            certificateName,
            requestClientCertificate,
            requireClientCertificate));
  }

  StreamSubscription<RawSecureSocket> listen(void onData(RawSecureSocket s),
                                             {void onError(error),
                                              void onDone(),
                                              bool cancelOnError}) {
    return _controller.stream.listen(onData,
                                     onError: onError,
                                     onDone: onDone,
                                     cancelOnError: cancelOnError);
  }

  /**
   * Returns the port used by this socket.
   */
  int get port => _socket.port;

  /**
   * Closes the socket. The returned future completes when the socket
   * is fully closed and is no longer bound.
   */
  Future<RawSecureServerSocket> close() {
    _closed = true;
    return _socket.close().then((_) => this);
  }

  void _onData(RawSocket connection) {
    var remotePort;
    try {
      remotePort = connection.remotePort;
    } catch (e) {
      // If connection is already closed, remotePort throws an exception.
      // Do nothing - connection is closed.
      return;
    }
    _RawSecureSocket.connect(
        connection.address,
        remotePort,
        certificateName,
        is_server: true,
        socket: connection,
        requestClientCertificate: requestClientCertificate,
        requireClientCertificate: requireClientCertificate)
    .then((RawSecureSocket secureConnection) {
      if (_closed) {
        secureConnection.close();
      } else {
        _controller.add(secureConnection);
      }
    }).catchError((e) {
      if (!_closed) {
        _controller.addError(e);
      }
    });
  }

  void _onError(e) {
    _controller.addError(e);
  }

  void _onDone() {
    _controller.close();
  }

  void _onPauseStateChange() {
    if (_controller.isPaused) {
      _subscription.pause();
    } else {
      _subscription.resume();
    }
  }

  void _onSubscriptionStateChange() {
    if (_controller.hasListener) {
      _subscription = _socket.listen(_onData,
                                     onDone: _onDone,
                                     onError: _onError);
    } else {
      close();
    }
  }
}


