// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Use the <code>chrome.sockets.tcp</code> API to send and receive data over the
// network using TCP connections. This API supersedes the TCP functionality
// previously found in the <code>chrome.socket</code> API.
namespace sockets.tcp {
  // The socket properties specified in the <code>create</code> or
  // <code>update</code> function. Each property is optional. If a property
  // value is not specified, a default value is used when calling
  // <code>create</code>, or the existing value if preserved when calling
  // <code>update</code>.
  dictionary SocketProperties {
    // Flag indicating if the socket is left open when the event page of
    // the application is unloaded (see
    // <a href="http://developer.chrome.com/apps/app_lifecycle.html">Manage App
    // Lifecycle</a>). The default value is "false." When the application is
    // loaded, any sockets previously opened with persistent=true can be fetched
    // with <code>getSockets</code>.
    boolean? persistent;

    // An application-defined string associated with the socket.
    DOMString? name;

    // The size of the buffer used to receive data. The default value is 4096.
    long? bufferSize;
  };

  // Result of <code>create</code> call.
  dictionary CreateInfo {
    // The ID of the newly created socket. Note that socket IDs created from
    // this API are not compatible with socket IDs created from other APIs, such
    // as the deprecated <code>$(ref:socket)</code> API.
    long socketId;
  };

  // Callback from the <code>create</code> method.
  // |createInfo| : The result of the socket creation.
  callback CreateCallback = void (CreateInfo createInfo);

  // Callback from the <code>connect</code> method.
  // |result| : The result code returned from the underlying network call.
  // A negative value indicates an error.
  callback ConnectCallback = void (long result);

  // Callback from the <code>disconnect</code> method.
  callback DisconnectCallback = void ();

  // Result of the <code>send</code> method.
  dictionary SendInfo {
    // The result code returned from the underlying network call.
    // A negative value indicates an error.
    long resultCode;

    // The number of bytes sent (if result == 0)
    long? bytesSent;
  };

  // Callback from the <code>send</code> method.
  // |sendInfo| : Result of the <code>send</code> method.
  callback SendCallback = void (SendInfo sendInfo);

  // Callback from the <code>close</code> method.
  callback CloseCallback = void ();

  // Callback from the <code>update</code> method.
  callback UpdateCallback = void ();

  // Callback from the <code>setPaused</code> method.
  callback SetPausedCallback = void ();

  // Callback from the <code>setKeepAliveCallback</code> method.
  // |result| : The result code returned from the underlying network call.
  // A negative value indicates an error.
  callback SetKeepAliveCallback = void (long result);

  // Callback from the <code>setNodeDelay</code> method.
  // |result| : The result code returned from the underlying network call.
  // A negative value indicates an error.
  callback SetNoDelayCallback = void (long result);

  dictionary TLSVersionConstraints {
    // The minimum and maximum acceptable versions of TLS. These will
    // be <code>tls1</code>, <code>tls1.1</code>, or <code>tls1.2</code>.
    DOMString? min;
    DOMString? max;
  };

  dictionary SecureOptions {
    TLSVersionConstraints? tlsVersion;
  };

  callback SecureCallback = void (long result);

  // Result of the <code>getInfo</code> method.
  dictionary SocketInfo {
    // The socket identifier.
    long socketId;

    // Flag indicating whether the socket is left open when the application is
    // suspended (see <code>SocketProperties.persistent</code>).
    boolean persistent;

    // Application-defined string associated with the socket.
    DOMString? name;

    // The size of the buffer used to receive data. If no buffer size has been
    // specified explictly, the value is not provided.
    long? bufferSize;

    // Flag indicating whether a connected socket blocks its peer from sending
    // more data (see <code>setPaused</code>).
    boolean paused;

    // Flag indicating whether the socket is connected to a remote peer.
    boolean connected;

    // If the underlying socket is connected, contains its local IPv4/6 address.
    DOMString? localAddress;

    // If the underlying socket is connected, contains its local port.
    long? localPort;

    // If the underlying socket is connected, contains the peer/ IPv4/6 address.
    DOMString? peerAddress;

    // If the underlying socket is connected, contains the peer port.
    long? peerPort;
  };

  // Callback from the <code>getInfo</code> method.
  // |socketInfo| : Object containing the socket information.
  callback GetInfoCallback = void (SocketInfo socketInfo);

  // Callback from the <code>getSockets</code> method.
  // |socketInfos| : Array of object containing socket information.
  callback GetSocketsCallback = void (SocketInfo[] socketInfos);

  // Data from an <code>onReceive</code> event.
  dictionary ReceiveInfo {
    // The socket identifier.
    long socketId;

    // The data received, with a maxium size of <code>bufferSize</code>.
    ArrayBuffer data;
  };

  // Data from an <code>onReceiveError</code> event.
  dictionary ReceiveErrorInfo {
    // The socket identifier.
    long socketId;

     // The result code returned from the underlying network call.
    long resultCode;
  };

  interface Functions {
    // Creates a TCP socket.
    // |properties| : The socket properties (optional).
    // |callback| : Called when the socket has been created.
    static void create(optional SocketProperties properties,
                       CreateCallback callback);

    // Updates the socket properties.
    // |socketId| : The socket identifier.
    // |properties| : The properties to update.
    // |callback| : Called when the properties are updated.
    static void update(long socketId,
                       SocketProperties properties,
                       optional UpdateCallback callback);

    // Enables or disables the application from receiving messages from its
    // peer. The default value is "false". Pausing a socket is typically used
    // by an application to throttle data sent by its peer. When a socket is
    // paused, no <code>onReceive</code> event is raised. When a socket is
    // connected and un-paused, <code>onReceive</code> events are raised again
    // when messages are received.
    static void setPaused(long socketId,
                          boolean paused,
                          optional SetPausedCallback callback);

    // Enables or disables the keep-alive functionality for a TCP connection.
    // |socketId| : The socket identifier.
    // |enable| : If true, enable keep-alive functionality.
    // |delay| : Set the delay seconds between the last data packet received
    // and the first keepalive probe. Default is 0.
    // |callback| : Called when the setKeepAlive attempt is complete.
    static void setKeepAlive(long socketId,
                             boolean enable,
                             optional long delay,
                             SetKeepAliveCallback callback);

    // Sets or clears <code>TCP_NODELAY</code> for a TCP connection. Nagle's
    // algorithm will be disabled when <code>TCP_NODELAY</code> is set.
    // |socketId| : The socket identifier.
    // |noDelay| : If true, disables Nagle's algorithm.
    // |callback| : Called when the setNoDelay attempt is complete.
    static void setNoDelay(long socketId,
                           boolean noDelay,
                           SetNoDelayCallback callback);

    // Connects the socket to a remote machine. When the <code>connect</code>
    // operation completes successfully, <code>onReceive</code> events are
    // raised when data is received from the peer. If a network error occurs
    // while the runtime is receiving packets, a <code>onReceiveError</code>
    // event is raised, at which point no more <code>onReceive</code> event will
    // be raised for this socket until the <code>resume</code> method is called.
    // |socketId| : The socket identifier.
    // |peerAddress| : The address of the remote machine. DNS name, IPv4 and
    //  IPv6 formats are supported.
    // |peerPort| : The port of the remote machine.
    // |callback| : Called when the connect attempt is complete.
    static void connect(long socketId,
                        DOMString peerAddress,
                        long peerPort,
                        ConnectCallback callback);

    // Disconnects the socket.
    // |socketId| : The socket identifier.
    // |callback| : Called when the disconnect attempt is complete.
    static void disconnect(long socketId,
                           optional DisconnectCallback callback);

    // Start a TLS client connection over the connected TCP client socket.
    // |socketId| : The existing, connected socket to use.
    // |options| : Constraints and parameters for the TLS connection.
    // |callback| : Called when the connection attempt is complete.
    static void secure(long socketId,
                       optional SecureOptions options,
                       SecureCallback callback);

    // Sends data on the given TCP socket.
    // |socketId| : The socket identifier.
    // |data| : The data to send.
    // |callback| : Called when the <code>send</code> operation completes.
    static void send(long socketId,
                     ArrayBuffer data,
                     SendCallback callback);

    // Closes the socket and releases the address/port the socket is bound to.
    // Each socket created should be closed after use. The socket id is no
    // no longer valid as soon at the function is called. However, the socket is
    // guaranteed to be closed only when the callback is invoked.
    // |socketId| : The socket identifier.
    // |callback| : Called when the <code>close</code> operation completes.
    static void close(long socketId,
                      optional CloseCallback callback);

    // Retrieves the state of the given socket.
    // |socketId| : The socket identifier.
    // |callback| : Called when the socket state is available.
    static void getInfo(long socketId,
                        GetInfoCallback callback);

    // Retrieves the list of currently opened sockets owned by the application.
    // |callback| : Called when the list of sockets is available.
    static void getSockets(GetSocketsCallback callback);
  };

  interface Events {
    // Event raised when data has been received for a given socket.
    // |info| : The event data.
    static void onReceive(ReceiveInfo info);

    // Event raised when a network error occured while the runtime was waiting
    // for data on the socket address and port. Once this event is raised, the
    // socket is set to <code>paused</code> and no more <code>onReceive</code>
    // events are raised for this socket.
    // |info| : The event data.
    static void onReceiveError(ReceiveErrorInfo info);
  };
};
