// Copyright (c) 2013, 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;

/**
 * [InternetAddressType] is the type an [InternetAddress]. Currently,
 * IP version 4 (IPv4) and IP version 6 (IPv6) are supported.
 */
class InternetAddressType {
  static const InternetAddressType IP_V4 = const InternetAddressType._(0);
  static const InternetAddressType IP_V6 = const InternetAddressType._(1);
  static const InternetAddressType ANY = const InternetAddressType._(-1);

  final int _value;

  const InternetAddressType._(this._value);

  factory InternetAddressType._from(int value) {
    if (value == 0) return IP_V4;
    if (value == 1) return IP_V6;
    throw new ArgumentError("Invalid type: $value");
  }

  /**
   * Get the name of the type, e.g. "IP_V4" or "IP_V6".
   */
  String get name {
    switch (_value) {
      case -1:
        return "ANY";
      case 0:
        return "IP_V4";
      case 1:
        return "IP_V6";
      default:
        throw new ArgumentError("Invalid InternetAddress");
    }
  }

  String toString() => "InternetAddressType: $name";
}

/**
 * An internet address.
 *
 * This object holds an internet address. If this internet address
 * is the result of a DNS lookup, the address also holds the hostname
 * used to make the lookup.
 * An Internet address combined with a port number represents an
 * endpoint to which a socket can connect or a listening socket can
 * bind.
 */
abstract class InternetAddress {
  /**
   * IP version 4 loopback address. Use this address when listening on
   * or connecting to the loopback adapter using IP version 4 (IPv4).
   */
  external static InternetAddress get LOOPBACK_IP_V4;

  /**
   * IP version 6 loopback address. Use this address when listening on
   * or connecting to the loopback adapter using IP version 6 (IPv6).
   */
  external static InternetAddress get LOOPBACK_IP_V6;

  /**
   * IP version 4 any address. Use this address when listening on
   * all adapters IP addresses using IP version 4 (IPv4).
   */
  external static InternetAddress get ANY_IP_V4;

  /**
   * IP version 6 any address. Use this address when listening on
   * all adapters IP addresses using IP version 6 (IPv6).
   */
  external static InternetAddress get ANY_IP_V6;

  /**
   * The [type] of the [InternetAddress] specified what IP protocol.
   */
  InternetAddressType type;

  /**
   * The numeric address of the host. For IPv4 addresses this is using
   * the dotted-decimal notation. For IPv6 it is using the
   * hexadecimal representation.
   */
  String get address;

  /**
   * The host used to lookup the address. If there is no host
   * associated with the address this returns the numeric address.
   */
  String get host;

  /**
   * Get the raw address of this [InternetAddress]. The result is either a
   * 4 or 16 byte long list. The returned list is a copy, making it possible
   * to change the list without modifying the [InternetAddress].
   */
  List<int> get rawAddress;

  /**
   * Returns true if the [InternetAddress] is a loopback address.
   */
  bool get isLoopback;

  /**
   * Returns true if the [InternetAddress]s scope is a link-local.
   */
  bool get isLinkLocal;

  /**
   * Returns true if the [InternetAddress]s scope is multicast.
   */
  bool get isMulticast;

  /**
   * Creates a new [InternetAddress] from a numeric address.
   *
   * If the address in [address] is not a numeric IPv4
   * (dotted-decimal notation) or IPv6 (hexadecimal representation).
   * address [ArgumentError] is thrown.
   */
  external factory InternetAddress(String address);

  /**
   * Perform a reverse dns lookup on the [address], creating a new
   * [InternetAddress] where the host field set to the result.
   */
  Future<InternetAddress> reverse();

  /**
   * Lookup a host, returning a Future of a list of
   * [InternetAddress]s. If [type] is [InternetAddressType.ANY], it
   * will lookup both IP version 4 (IPv4) and IP version 6 (IPv6)
   * addresses. If [type] is either [InternetAddressType.IP_V4] or
   * [InternetAddressType.IP_V6] it will only lookup addresses of the
   * specified type. The order of the list can, and most likely will,
   * change over time.
   */
  external static Future<List<InternetAddress>> lookup(String host,
      {InternetAddressType type: InternetAddressType.ANY});

  /**
   * Clones the given [address] with the new [host].
   *
   * The [address] must be an [InternetAddress] that was created with one
   * of the static methods of this class.
   */
  external static InternetAddress _cloneWithNewHost(
      InternetAddress address, String host);
}

/**
 * A [NetworkInterface] represents an active network interface on the current
 * system. It contains a list of [InternetAddress]es that are bound to the
 * interface.
 */
abstract class NetworkInterface {
  /**
   * Get the name of the [NetworkInterface].
   */
  String get name;

  /**
   * Get the index of the [NetworkInterface].
   */
  int get index;

  /**
   * Get a list of [InternetAddress]es currently bound to this
   * [NetworkInterface].
   */
  List<InternetAddress> get addresses;

  /**
   * Whether [list] is supported.
   *
   * [list] is currently unsupported on Android.
   */
  external static bool get listSupported;

  /**
   * Query the system for [NetworkInterface]s.
   *
   * If [includeLoopback] is `true`, the returned list will include the
   * loopback device. Default is `false`.
   *
   * If [includeLinkLocal] is `true`, the list of addresses of the returned
   * [NetworkInterface]s, may include link local addresses. Default is `false`.
   *
   * If [type] is either [InternetAddressType.IP_V4] or
   * [InternetAddressType.IP_V6] it will only lookup addresses of the
   * specified type. Default is [InternetAddressType.ANY].
   */
  external static Future<List<NetworkInterface>> list(
      {bool includeLoopback: false,
      bool includeLinkLocal: false,
      InternetAddressType type: InternetAddressType.ANY});
}

/**
 * A [RawServerSocket] represents a listening socket, and provides a
 * stream of low-level [RawSocket] objects, one for each connection
 * made to the listening socket.
 *
 * See [RawSocket] for more info.
 */
abstract class RawServerSocket implements Stream<RawSocket> {
  /**
   * Returns a future for a [:RawServerSocket:]. 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 an IP version 6 (IPv6) address is used, both IP version 6
   * (IPv6) and version 4 (IPv4) connections will be accepted. To
   * restrict this to version 6 (IPv6) only, use [v6Only] to set
   * version 6 only.
   *
   * 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.
   *
   * The optional argument [shared] specifies whether additional RawServerSocket
   * objects can bind to the same combination of `address`, `port` and `v6Only`.
   * If `shared` is `true` and more `RawServerSocket`s from this isolate or
   * other isolates are bound to the port, then the incoming connections will be
   * distributed among all the bound `RawServerSocket`s. Connections can be
   * distributed over multiple isolates this way.
   */
  external static Future<RawServerSocket> bind(address, int port,
      {int backlog: 0, bool v6Only: false, bool shared: false});

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

  /**
   * Returns the address used by this socket.
   */
  InternetAddress get address;

  /**
   * Closes the socket. The returned future completes when the socket
   * is fully closed and is no longer bound.
   */
  Future<RawServerSocket> close();
}

/**
 * A [ServerSocket] represents a listening socket, and provides a
 * stream of [Socket] objects, one for each connection made to the
 * listening socket.
 *
 * See [Socket] for more info.
 */
abstract class ServerSocket implements Stream<Socket> {
  /**
   * Returns a future for a [:ServerSocket:]. 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 an IP version 6 (IPv6) address is used, both IP version 6
   * (IPv6) and version 4 (IPv4) connections will be accepted. To
   * restrict this to version 6 (IPv6) only, use [v6Only] to set
   * version 6 only.
   *
   * 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.
   *
   * The optional argument [shared] specifies whether additional ServerSocket
   * objects can bind to the same combination of `address`, `port` and `v6Only`.
   * If `shared` is `true` and more `ServerSocket`s from this isolate or other
   * isolates are bound to the port, then the incoming connections will be
   * distributed among all the bound `ServerSocket`s. Connections can be
   * distributed over multiple isolates this way.
   */
  external static Future<ServerSocket> bind(address, int port,
      {int backlog: 0, bool v6Only: false, bool shared: false});

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

  /**
   * Returns the address used by this socket.
   */
  InternetAddress get address;

  /**
   * Closes the socket. The returned future completes when the socket
   * is fully closed and is no longer bound.
   */
  Future<ServerSocket> close();
}

/**
 * The [SocketDirection] is used as a parameter to [Socket.close] and
 * [RawSocket.close] to close a socket in the specified direction(s).
 */
class SocketDirection {
  static const SocketDirection RECEIVE = const SocketDirection._(0);
  static const SocketDirection SEND = const SocketDirection._(1);
  static const SocketDirection BOTH = const SocketDirection._(2);
  final _value;

  const SocketDirection._(this._value);
}

/**
 * The [SocketOption] is used as a parameter to [Socket.setOption] and
 * [RawSocket.setOption] to set customize the behaviour of the underlying
 * socket.
 */
class SocketOption {
  /**
   * Enable or disable no-delay on the socket. If TCP_NODELAY is enabled, the
   * socket will not buffer data internally, but instead write each data chunk
   * as an individual TCP packet.
   *
   * TCP_NODELAY is disabled by default.
   */
  static const SocketOption TCP_NODELAY = const SocketOption._(0);

  static const SocketOption _IP_MULTICAST_LOOP = const SocketOption._(1);
  static const SocketOption _IP_MULTICAST_HOPS = const SocketOption._(2);
  static const SocketOption _IP_MULTICAST_IF = const SocketOption._(3);
  static const SocketOption _IP_BROADCAST = const SocketOption._(4);
  final _value;

  const SocketOption._(this._value);
}

/**
 * Events for the [RawSocket].
 */
class RawSocketEvent {
  static const RawSocketEvent READ = const RawSocketEvent._(0);
  static const RawSocketEvent WRITE = const RawSocketEvent._(1);
  static const RawSocketEvent READ_CLOSED = const RawSocketEvent._(2);
  static const RawSocketEvent CLOSED = const RawSocketEvent._(3);
  final int _value;

  const RawSocketEvent._(this._value);
  String toString() {
    return const [
      'RawSocketEvent:READ',
      'RawSocketEvent:WRITE',
      'RawSocketEvent:READ_CLOSED',
      'RawSocketEvent:CLOSED'
    ][_value];
  }
}

/**
 * The [RawSocket] is a low-level interface to a socket, exposing the raw
 * events signaled by the system. It's a [Stream] of [RawSocketEvent]s.
 */
abstract class RawSocket implements Stream<RawSocketEvent> {
  /**
   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.READ]
   * events. Default is [:true:].
   */
  bool readEventsEnabled;

  /**
   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.WRITE]
   * events. Default is [:true:].
   * This is a one-shot listener, and writeEventsEnabled must be set
   * to true again to receive another write event.
   */
  bool writeEventsEnabled;

  /**
   * Creates a new socket connection to the host and port and returns a [Future]
   * that will complete with either a [RawSocket] once connected or an error
   * if the host-lookup or connection failed.
   *
   * [host] can either be a [String] or an [InternetAddress]. If [host] is a
   * [String], [connect] will perform a [InternetAddress.lookup] and try
   * all returned [InternetAddress]es, until connected. Unless a
   * connection was established, the error from the first failing connection is
   * returned.
   *
   * The argument [sourceAddress] can be used to specify the local
   * address to bind when making the connection. `sourceAddress` can either
   * be a `String` or an `InternetAddress`. If a `String` is passed it must
   * hold a numeric IP address.
   *
   * The argument [timeout] is used to specify the maximum allowed time to wait
   * for a connection to be established. If [timeout] is longer than the system
   * level timeout duration, a timeout may occur sooner than specified in
   * [timeout]. On timeout, a [SocketException] is thrown and all ongoing
   * connection attempts to [host] are cancelled.
   */
  external static Future<RawSocket> connect(host, int port,
      {sourceAddress, Duration timeout});

  /**
   * Returns the number of received and non-read bytes in the socket that
   * can be read.
   */
  int available();

  /**
   * Read up to [len] bytes from the socket. This function is
   * non-blocking and will only return data if data is available. The
   * number of bytes read can be less then [len] if fewer bytes are
   * available for immediate reading. If no data is available [:null:]
   * is returned.
   */
  List<int> read([int len]);

  /**
   * Writes up to [count] bytes of the buffer from [offset] buffer offset to
   * the socket. The number of successfully written bytes is returned. This
   * function is non-blocking and will only write data if buffer space is
   * available in the socket.
   *
   * The default value for [offset] is 0, and the default value for [count] is
   * [:buffer.length - offset:].
   */
  int write(List<int> buffer, [int offset, int count]);

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

  /**
   * Returns the remote port connected to by this socket.
   */
  int get remotePort;

  /**
   * Returns the [InternetAddress] used to connect this socket.
   */
  InternetAddress get address;

  /**
   * Returns the remote [InternetAddress] connected to by this socket.
   */
  InternetAddress get remoteAddress;

  /**
   * Closes the socket. Returns a Future that completes with [this] when the
   * underlying connection is completely destroyed.
   *
   * Calling [close] will never throw an exception
   * and calling it several times is supported. Calling [close] can result in
   * a [RawSocketEvent.READ_CLOSED] event.
   */
  Future<RawSocket> close();

  /**
   * Shutdown the socket in the [direction]. Calling [shutdown] will never
   * throw an exception and calling it several times is supported. Calling
   * shutdown with either [SocketDirection.BOTH] or [SocketDirection.RECEIVE]
   * can result in a [RawSocketEvent.READ_CLOSED] event.
   */
  void shutdown(SocketDirection direction);

  /**
   * Use [setOption] to customize the [RawSocket]. See [SocketOption] for
   * available options.
   *
   * Returns [:true:] if the option was set successfully, false otherwise.
   */
  bool setOption(SocketOption option, bool enabled);
}

/**
 * A high-level class for communicating over a TCP socket.
 *
 * The [Socket] exposes both a [Stream] and a [IOSink] interface, making it
 * ideal for using together with other [Stream]s.
 */
abstract class Socket implements Stream<List<int>>, IOSink {
  /**
   * Creates a new socket connection to the host and port and returns a [Future]
   * that will complete with either a [Socket] once connected or an error
   * if the host-lookup or connection failed.
   *
   * [host] can either be a [String] or an [InternetAddress]. If [host] is a
   * [String], [connect] will perform a [InternetAddress.lookup] and try
   * all returned [InternetAddress]es, until connected. Unless a
   * connection was established, the error from the first failing connection is
   * returned.
   *
   * The argument [sourceAddress] can be used to specify the local
   * address to bind when making the connection. `sourceAddress` can either
   * be a `String` or an `InternetAddress`. If a `String` is passed it must
   * hold a numeric IP address.
   *
   * The argument [timeout] is used to specify the maximum allowed time to wait
   * for a connection to be established. If [timeout] is longer than the system
   * level timeout duration, a timeout may occur sooner than specified in
   * [timeout]. On timeout, a [SocketException] is thrown and all ongoing
   * connection attempts to [host] are cancelled.
   */
  external static Future<Socket> connect(host, int port,
      {sourceAddress, Duration timeout});

  /**
   * Destroy the socket in both directions. Calling [destroy] will make the
   * send a close event on the stream and will no longer react on data being
   * piped to it.
   *
   * Call [close](inherited from [IOSink]) to only close the [Socket]
   * for sending data.
   */
  void destroy();

  /**
   * Use [setOption] to customize the [RawSocket]. See [SocketOption] for
   * available options.
   *
   * Returns [:true:] if the option was set successfully, false otherwise.
   */
  bool setOption(SocketOption option, bool enabled);

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

  /**
   * Returns the remote port connected to by this socket.
   */
  int get remotePort;

  /**
   * Returns the [InternetAddress] used to connect this socket.
   */
  InternetAddress get address;

  /**
   * Returns the remote [InternetAddress] connected to by this socket.
   */
  InternetAddress get remoteAddress;

  Future close();

  Future get done;
}

/**
 * Datagram package. Data send to and received from datagram sockets
 * contains the internet address and port of the destination or source
 * togeter with the data.
 */
class Datagram {
  List<int> data;
  InternetAddress address;
  int port;

  Datagram(this.data, this.address, this.port);
}

/**
 * The [RawDatagramSocket] is a low-level interface to an UDP socket,
 * exposing the raw events signaled by the system. It's a [Stream] of
 * [RawSocketEvent]s.
 *
 * Note that the event [RawSocketEvent.READ_CLOSED] will never be
 * received as an UDP socket cannot be closed by a remote peer.
 */
abstract class RawDatagramSocket extends Stream<RawSocketEvent> {
  /**
   * Set or get, if the [RawDatagramSocket] should listen for
   * [RawSocketEvent.READ] events. Default is [:true:].
   */
  bool readEventsEnabled;

  /**
   * Set or get, if the [RawDatagramSocket] should listen for
   * [RawSocketEvent.WRITE] events. Default is [:true:].  This is a
   * one-shot listener, and writeEventsEnabled must be set to true
   * again to receive another write event.
   */
  bool writeEventsEnabled;

  /**
   * Set or get, whether multicast traffic is looped back to the host.
   *
   * By default multicast loopback is enabled.
   */
  bool multicastLoopback;

  /**
   * Set or get, the maximum network hops for multicast packages
   * originating from this socket.
   *
   * For IPv4 this is referred to as TTL (time to live).
   *
   * By default this value is 1 causing multicast traffic to stay on
   * the local network.
   */
  int multicastHops;

  /**
   * Set or get, the network interface used for outgoing multicast packages.
   *
   * A value of `null`indicate that the system chooses the network
   * interface to use.
   *
   * By default this value is `null`
   */
  NetworkInterface multicastInterface;

  /**
   * Set or get, whether IPv4 broadcast is enabled.
   *
   * IPv4 broadcast needs to be enabled by the sender for sending IPv4
   * broadcast packages. By default IPv4 broadcast is disabled.
   *
   * For IPv6 there is no general broadcast mechanism. Use multicast
   * instead.
   */
  bool broadcastEnabled;

  /**
   * Creates a new raw datagram socket binding it to an address and
   * port.
   */
  external static Future<RawDatagramSocket> bind(host, int port,
      {bool reuseAddress: true});

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

  /**
   * Returns the address used by this socket.
   */
  InternetAddress get address;

  /**
   * Close the datagram socket.
   */
  void close();

  /**
   * Send a datagram.
   *
   * Returns the number of bytes written. This will always be either
   * the size of [buffer] or `0`.
   */
  int send(List<int> buffer, InternetAddress address, int port);

  /**
   * Receive a datagram. If there are no datagrams available `null` is
   * returned.
   *
   * The maximum length of the datagram that can be received is 65503 bytes.
   */
  Datagram receive();

  /**
   * Join a multicast group.
   *
   * If an error occur when trying to join the multicast group an
   * exception is thrown.
   */
  void joinMulticast(InternetAddress group, [NetworkInterface interface]);

  /**
   * Leave a multicast group.
   *
   * If an error occur when trying to join the multicase group an
   * exception is thrown.
   */
  void leaveMulticast(InternetAddress group, [NetworkInterface interface]);
}

class SocketException implements IOException {
  final String message;
  final OSError osError;
  final InternetAddress address;
  final int port;

  const SocketException(this.message, {this.osError, this.address, this.port});
  const SocketException.closed()
      : message = 'Socket has been closed',
        osError = null,
        address = null,
        port = null;

  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write("SocketException");
    if (!message.isEmpty) {
      sb.write(": $message");
      if (osError != null) {
        sb.write(" ($osError)");
      }
    } else if (osError != null) {
      sb.write(": $osError");
    }
    if (address != null) {
      sb.write(", address = ${address.host}");
    }
    if (port != null) {
      sb.write(", port = $port");
    }
    return sb.toString();
  }
}
