package com.foxx.androidcast.network;

/*********************************************************************
 * CastTransport.java
 * Created at: Fri 15 May 2026 16:49:02 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * interface CastTransport
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (5 commits, 55 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	cacc0f092505305b2c75a7a0479a1c837a39a05de5ace51d17267d54116262be
**********************************************************************/
import com.foxx.androidcast.network.transport.TransportLossStats;

import java.io.Closeable;
import java.io.IOException;

/** Pluggable stream transport (TCP or UDP). */
public interface CastTransport extends Closeable {
    /** Optional proto header context; ignored when null. */
    default void setFramingContext(CastFramingContext context) {}

    /** Drops inbound wire packets whose session id does not match the active cast. */
    default void setInboundSessionGate(CastSessionGate gate) {}
    /** Server: bind and wait for first peer datagram / connection. */
    void listen(int port) throws IOException;

    /** Server: bind listen socket only (port open for inbound TCP). */
    default void prepareListen(int port) throws IOException {
        listen(port);
    }

    /** Server: block until a client connects (TCP) or no-op (UDP). */
    default void acceptClient() throws IOException {}

    /** Client: connect to host:port. */
    void connect(String host, int port) throws IOException;

    void send(byte type, byte[] payload) throws IOException;

    /** Blocks until a message arrives or timeout. Returns null on timeout. */
    CastProtocol.Message receive(int timeoutMs) throws IOException;

    String getModeLabel();

    /** Loss/damage counters when supported (UDP); empty stats otherwise. */
    default TransportLossStats getLossStats() {
        return new TransportLossStats();
    }

    /** Server: drop the active client socket but keep the listen socket bound. */
    default void releaseConnection() {
        close();
    }

    @Override
    void close();
}
