package com.foxx.androidcast.network.transport;

/*********************************************************************
 * StreamProtectionCapability.java
 * Created at: Tue 19 May 2026 12:23:39 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class StreamProtectionCapability
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (2 commits, 53 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	2964f9d7b3c1de2f07bba4f8974f0694e8e70ca5c826053a8b45113007fb0655
**********************************************************************/
import com.foxx.androidcast.CastSettings;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

/** Runtime FEC/NACK implementations on this device (not a user setting). */
public final class StreamProtectionCapability {
    private StreamProtectionCapability() {}

    /** Wire value: receiver supports negotiation from {@link #receiverImplementations()}. */
    public static CastSettings.StreamProtection handshakeAdvertisement() {
        return CastSettings.StreamProtection.AUTO;
    }

    public static boolean isAutoAdvertisement(CastSettings.StreamProtection mode) {
        return mode == null || mode == CastSettings.StreamProtection.AUTO;
    }

    /** Modes this build can encode/decode over UDP. */
    public static EnumSet<CastSettings.StreamProtection> receiverImplementations() {
        return EnumSet.of(
                CastSettings.StreamProtection.FEC_3_4,
                CastSettings.StreamProtection.FEC_REED_SOLOMON,
                CastSettings.StreamProtection.NACK,
                CastSettings.StreamProtection.FEC_NACK,
                CastSettings.StreamProtection.NONE);
    }

    public static boolean supports(CastSettings.StreamProtection mode) {
        CastSettings.StreamProtection n = StreamProtectionNegotiator.normalize(mode);
        return receiverImplementations().contains(n);
    }

    public static EnumSet<CastSettings.StreamProtection> resolveRemoteCapability(
            CastSettings.StreamProtection remote) {
        if (isAutoAdvertisement(remote)) {
            return receiverImplementations();
        }
        CastSettings.StreamProtection n = StreamProtectionNegotiator.normalize(remote);
        if (supports(n)) {
            return EnumSet.of(n);
        }
        return EnumSet.of(CastSettings.StreamProtection.NONE);
    }

    /** Modes this device advertises on the wire (handshake uses AUTO → full set). */
    public static List<String> advertisedProtectionInOrder() {
        List<String> out = new ArrayList<>();
        out.add("AUTO (handshake)");
        for (CastSettings.StreamProtection mode : receiverImplementations()) {
            out.add(mode.name());
        }
        return out;
    }
}
