/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jakarta.websocket;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;


public interface RemoteEndpoint {

    interface Async extends RemoteEndpoint {

        /**
         * Obtain the timeout (in milliseconds) for sending a message
         * asynchronously. The default value is determined by
         * {@link WebSocketContainer#getDefaultAsyncSendTimeout()}.
         * @return  The current send timeout in milliseconds. A non-positive
         *          value means an infinite timeout.
         */
        long getSendTimeout();

        /**
         * Set the timeout (in milliseconds) for sending a message
         * asynchronously. The default value is determined by
         * {@link WebSocketContainer#getDefaultAsyncSendTimeout()}.
         * @param timeout   The new timeout for sending messages asynchronously
         *                  in milliseconds. A non-positive value means an
         *                  infinite timeout.
         */
        void setSendTimeout(long timeout);

        /**
         * Send the message asynchronously, using the SendHandler to signal to the
         * client when the message has been sent.
         * @param text          The text message to send
         * @param completion    Used to signal to the client when the message has
         *                      been sent
         */
        void sendText(String text, SendHandler completion);

        /**
         * Send the message asynchronously, using the Future to signal to the
         * client when the message has been sent.
         * @param text          The text message to send
         * @return A Future that signals when the message has been sent.
         */
        Future<Void> sendText(String text);

        /**
         * Send the message asynchronously, using the Future to signal to the client
         * when the message has been sent.
         * @param data          The text message to send
         * @return A Future that signals when the message has been sent.
         * @throws IllegalArgumentException if {@code data} is {@code null}.
         */
        Future<Void> sendBinary(ByteBuffer data);

        /**
         * Send the message asynchronously, using the SendHandler to signal to the
         * client when the message has been sent.
         * @param data          The text message to send
         * @param completion    Used to signal to the client when the message has
         *                      been sent
         * @throws IllegalArgumentException if {@code data} or {@code completion}
         *                      is {@code null}.
         */
        void sendBinary(ByteBuffer data, SendHandler completion);

        /**
         * Encodes object as a message and sends it asynchronously, using the
         * Future to signal to the client when the message has been sent.
         * @param obj           The object to be sent.
         * @return A Future that signals when the message has been sent.
         * @throws IllegalArgumentException if {@code obj} is {@code null}.
         */
        Future<Void> sendObject(Object obj);

        /**
         * Encodes object as a message and sends it asynchronously, using the
         * SendHandler to signal to the client when the message has been sent.
         * @param obj           The object to be sent.
         * @param completion    Used to signal to the client when the message has
         *                      been sent
         * @throws IllegalArgumentException if {@code obj} or
         *                      {@code completion} is {@code null}.
         */
        void sendObject(Object obj, SendHandler completion);

    }

    interface Basic extends RemoteEndpoint {

        /**
         * Send the message, blocking until the message is sent.
         * @param text  The text message to send.
         * @throws IllegalArgumentException if {@code text} is {@code null}.
         * @throws IOException if an I/O error occurs during the sending of the
         *                     message.
         */
        void sendText(String text) throws IOException;

        /**
         * Send the message, blocking until the message is sent.
         * @param data  The binary message to send
         * @throws IllegalArgumentException if {@code data} is {@code null}.
         * @throws IOException if an I/O error occurs during the sending of the
         *                     message.
         */
        void sendBinary(ByteBuffer data) throws IOException;

        /**
         * Sends part of a text message to the remote endpoint. Once the first part
         * of a message has been sent, no other text or binary messages may be sent
         * until all remaining parts of this message have been sent.
         *
         * @param fragment  The partial message to send
         * @param isLast    <code>true</code> if this is the last part of the
         *                  message, otherwise <code>false</code>
         * @throws IllegalArgumentException if {@code fragment} is {@code null}.
         * @throws IOException if an I/O error occurs during the sending of the
         *                     message.
         */
        void sendText(String fragment, boolean isLast) throws IOException;

        /**
         * Sends part of a binary message to the remote endpoint. Once the first
         * part of a message has been sent, no other text or binary messages may be
         * sent until all remaining parts of this message have been sent.
         *
         * @param partialByte   The partial message to send
         * @param isLast        <code>true</code> if this is the last part of the
         *                      message, otherwise <code>false</code>
         * @throws IllegalArgumentException if {@code partialByte} is
         *                     {@code null}.
         * @throws IOException if an I/O error occurs during the sending of the
         *                     message.
         */
        void sendBinary(ByteBuffer partialByte, boolean isLast) throws IOException;

        OutputStream getSendStream() throws IOException;

        Writer getSendWriter() throws IOException;

        /**
         * Encodes object as a message and sends it to the remote endpoint.
         * @param data  The object to be sent.
         * @throws EncodeException if there was a problem encoding the
         *                     {@code data} object as a websocket message.
         * @throws IllegalArgumentException if {@code data} is {@code null}.
         * @throws IOException if an I/O error occurs during the sending of the
         *                     message.
         */
        void sendObject(Object data) throws IOException, EncodeException;

    }
    /**
     * Enable or disable the batching of outgoing messages for this endpoint. If
     * batching is disabled when it was previously enabled then this method will
     * block until any currently batched messages have been written.
     *
     * @param batchingAllowed   New setting
     * @throws IOException      If changing the value resulted in a call to
     *                          {@link #flushBatch()} and that call threw an
     *                          {@link IOException}.
     */
    void setBatchingAllowed(boolean batchingAllowed) throws IOException;

    /**
     * Obtains the current batching status of the endpoint.
     *
     * @return <code>true</code> if batching is enabled, otherwise
     *         <code>false</code>.
     */
    boolean getBatchingAllowed();

    /**
     * Flush any currently batched messages to the remote endpoint. This method
     * will block until the flush completes.
     *
     * @throws IOException If an I/O error occurs while flushing
     */
    void flushBatch() throws IOException;

    /**
     * Send a ping message blocking until the message has been sent. Note that
     * if a message is in the process of being sent asynchronously, this method
     * will block until that message and this ping has been sent.
     *
     * @param applicationData   The payload for the ping message
     *
     * @throws IOException If an I/O error occurs while sending the ping
     * @throws IllegalArgumentException if the applicationData is too large for
     *         a control message (max 125 bytes)
     */
    void sendPing(ByteBuffer applicationData)
            throws IOException, IllegalArgumentException;

    /**
     * Send a pong message blocking until the message has been sent. Note that
     * if a message is in the process of being sent asynchronously, this method
     * will block until that message and this pong has been sent.
     *
     * @param applicationData   The payload for the pong message
     *
     * @throws IOException If an I/O error occurs while sending the pong
     * @throws IllegalArgumentException if the applicationData is too large for
     *         a control message (max 125 bytes)
     */
    void sendPong(ByteBuffer applicationData)
            throws IOException, IllegalArgumentException;
}

