// 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.udp</code> API to send and receive data over the
// network using UDP connections. This API supersedes the UDP functionality
// previously found in the "socket" API.
namespace sockets.udp {
  // 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. If the buffer is too small
    // to receive the UDP packet, data is lost. 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>bind</code> method.
  // |result| : The result code returned from the underlying network call.
  // A negative value indicates an error.
  callback BindCallback = void (long result);

  // 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 ();

  // 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 the socket is blocked from firing onReceive
    // events.
    boolean paused;

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

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

  // 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);

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

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

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

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

  // Callback from the <code>getJoinedGroupsCallback</code> method.
  // |groups| : Array of groups the socket joined.
  callback GetJoinedGroupsCallback = void (DOMString[] groups);

  // Callback from the <code>setBroadcast</code> method.
  // |result| : The result code returned from the underlying network call.
  callback SetBroadcastCallback = void (long result);

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

    // The UDP packet content (truncated to the current buffer size).
    ArrayBuffer data;

    // The address of the host the packet comes from.
    DOMString remoteAddress;

     // The port of the host the packet comes from.
    long remotePort;
  };

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

     // The result code returned from the underlying recvfrom() call.
    long resultCode;
  };

  interface Functions {
    // Creates a UDP socket with the given properties.
    // |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 ID.
    // |properties| : The properties to update.
    // |callback| : Called when the properties are updated.
    static void update(long socketId,
                       SocketProperties properties,
                       optional UpdateCallback callback);

    // Pauses or unpauses a socket. A paused socket is blocked from firing
    // <code>onReceive</code> events.
    // |connectionId| : The socket ID.
    // |paused| : Flag to indicate whether to pause or unpause.
    // |callback| : Called when the socket has been successfully paused or
    // unpaused.
    static void setPaused(long socketId,
                          boolean paused,
                          optional SetPausedCallback callback);

    // Binds the local address and port for the socket. For a client socket, it
    // is recommended to use port 0 to let the platform pick a free port.
    //
    // Once the <code>bind</code> operation completes successfully,
    // <code>onReceive</code> events are raised when UDP packets arrive on the
    // address/port specified -- unless the socket is paused.
    //
    // |socketId| : The socket ID.
    // |address| : The address of the local machine. DNS name, IPv4 and IPv6
    // formats are supported. Use "0.0.0.0" to accept packets from all local
    // available network interfaces.
    // |port| : The port of the local machine. Use "0" to bind to a free port.
    // |callback| : Called when the <code>bind</code> operation completes.
    static void bind(long socketId,
                     DOMString address,
                     long port,
                     BindCallback callback);

    // Sends data on the given socket to the given address and port. The socket
    // must be bound to a local port before calling this method.
    // |socketId| : The socket ID.
    // |data| : The data to send.
    // |address| : The address of the remote machine.
    // |port| : The port of the remote machine.
    // |callback| : Called when the <code>send</code> operation completes.
    static void send(long socketId,
                     ArrayBuffer data,
                     DOMString address,
                     long port,
                     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
    // 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 ID.
    // |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 ID.
    // |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);

    // Joins the multicast group and starts to receive packets from that group.
    // The socket must be bound to a local port before calling this method.
    // |socketId| : The socket ID.
    // |address| : The group address to join. Domain names are not supported.
    // |callback| : Called when the <code>joinGroup</code> operation completes.
    static void joinGroup(long socketId,
                          DOMString address,
                          JoinGroupCallback callback);

    // Leaves the multicast group previously joined using
    // <code>joinGroup</code>. This is only necessary to call if you plan to
    // keep using the socketafterwards, since it will be done automatically by
    // the OS when the socket is closed.
    //
    // Leaving the group will prevent the router from sending multicast
    // datagrams to the local host, presuming no other process on the host is
    // still joined to the group.
    //
    // |socketId| : The socket ID.
    // |address| : The group address to leave. Domain names are not supported.
    // |callback| : Called when the <code>leaveGroup</code> operation completes.
    static void leaveGroup(long socketId,
                           DOMString address,
                           LeaveGroupCallback callback);

    // Sets the time-to-live of multicast packets sent to the multicast group.
    //
    // Calling this method does not require multicast permissions.
    //
    // |socketId| : The socket ID.
    // |ttl| : The time-to-live value.
    // |callback| : Called when the configuration operation completes.
    static void setMulticastTimeToLive(
        long socketId,
        long ttl,
        SetMulticastTimeToLiveCallback callback);

    // Sets whether multicast packets sent from the host to the multicast group
    // will be looped back to the host.
    //
    // Note: the behavior of <code>setMulticastLoopbackMode</code> is slightly
    // different between Windows and Unix-like systems. The inconsistency
    // happens only when there is more than one application on the same host
    // joined to the same multicast group while having different settings on
    // multicast loopback mode. On Windows, the applications with loopback off
    // will not RECEIVE the loopback packets; while on Unix-like systems, the
    // applications with loopback off will not SEND the loopback packets to
    // other applications on the same host. See MSDN: http://goo.gl/6vqbj
    //
    // Calling this method does not require multicast permissions.
    //
    // |socketId| : The socket ID.
    // |enabled| : Indicate whether to enable loopback mode.
    // |callback| : Called when the configuration operation completes.
    static void setMulticastLoopbackMode(
        long socketId,
        boolean enabled,
        SetMulticastLoopbackModeCallback callback);

    // Gets the multicast group addresses the socket is currently joined to.
    // |socketId| : The socket ID.
    // |callback| : Called with an array of strings of the result.
    static void getJoinedGroups(long socketId,
                                GetJoinedGroupsCallback callback);

    // Enables or disables broadcast packets on this socket.
    //
    // |socketId| : The socket ID.
    // |enabled| : <code>true</code> to enable broadcast packets,
    // <code>false</code> to disable them.
    static void setBroadcast(long socketId,
                             boolean enabled,
                             SetBroadcastCallback callback);
  };

  interface Events {
    // Event raised when a UDP packet has been received for the 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 paused and no more <code>onReceive</code> events will be raised
    // for this socket until the socket is resumed.
    // |info| : The event data.
    static void onReceiveError(ReceiveErrorInfo info);
  };
};
