// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.azure.proton.transport.ws;

import java.nio.ByteBuffer;
import java.util.Map;

/**
 * Provides interface for WebSocket.
 */
public interface WebSocket {
    /**
     * States that the web socket can be in.
     */
    enum WebSocketState {
        /**
         * WebSocket.
         */
        PN_WS_NOT_STARTED,
        /**
         * Pending connection.
         */
        PN_WS_CONNECTING,
        /**
         * Connected and messages flow.
         */
        PN_WS_CONNECTED_FLOW,
        /**
         * Connected and ping-pong.
         */
        PN_WS_CONNECTED_PONG,
        /**
         * Connected and received a close.
         */
        PN_WS_CONNECTED_CLOSING,
        /**
         * Connection closed.
         */
        PN_WS_CLOSED,
        /**
         * Connection failed.
         */
        PN_WS_FAILED
    }

    /**
     * States for the web socket when reading from the underlying buffer.
     */
    enum WebSocketFrameReadState {
        /**
         * The initial read.
         */
        INIT_READ,

        /**
         * Reading chunks of bytes until a full header is read.
         */
        CHUNK_READ,

        /**
         * Continue reading bytes until correct number of bytes are read.
         */
        CONTINUED_FRAME_READ,

        /**
         * Full header has been read.
         */
        HEADER_READ,

        /**
         * An error reading.
         */
        READ_ERROR
    }

    /**
     * Configure WebSocket connection.
     *
     * @param host              the hots name
     * @param path              the resource path
     * @param query             the query
     * @param port              the port
     * @param protocol          the base protocol
     * @param additionalHeaders the Map of additional headers
     * @param webSocketHandler  the web socket handler
     */
    void configure(
            String host,
            String path,
            String query,
            int port,
            String protocol,
            Map<String, String> additionalHeaders,
            WebSocketHandler webSocketHandler);

    /**
     * Add WebSocket frame to send the given buffer.
     *
     * @param srcBuffer the source buffer
     * @param dstBuffer the destination buffer
     */
    void wrapBuffer(ByteBuffer srcBuffer, ByteBuffer dstBuffer);

    /**
     * Remove WebSocket frame from the given buffer.
     *
     * @param buffer the buffer to unwrap
     * @return The payload of the given WebSocket frame.
     */
    WebSocketHandler.WebsocketTuple unwrapBuffer(ByteBuffer buffer);

    /**
     * Access the handler for WebSocket functions.
     *
     * @return The WebSocket handler class.
     */
    WebSocketHandler getWebSocketHandler();

    /**
     * Access the current state of the layer.
     *
     * @return The state of the WebSocket layer.
     */
    WebSocketState getState();

    /**
     * Access if WebSocket enabled .
     *
     * @return True if WebSocket enabled otherwise false.
     */
    Boolean getEnabled();

    /**
     * Access the output buffer (read only).
     *
     * @return The current output buffer.
     */
    ByteBuffer getOutputBuffer();

    /**
     * Access the input buffer (read only).
     *
     * @return The current input buffer.
     */
    ByteBuffer getInputBuffer();

    /**
     * Access the ping buffer (read only).
     *
     * @return The ping input buffer.
     */
    ByteBuffer getPingBuffer();

    /**
     * Access the web socket input buffer (read only).
     *
     * @return The wsInputBuffer input buffer.
     */
    ByteBuffer getWsInputBuffer();
}
