package com.foxx.androidcast.network.transport;

/*********************************************************************
 * StreamProtectionNegotiatorTest.java
 * Created at: Sun 17 May 2026 22:49:49 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class StreamProtectionNegotiatorTest
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (3 commits, 117 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	cc4bd7ad0bc870742d3e39bca93ce8e0b8f8ea147fa6c60c06256fa52dfc955e
**********************************************************************/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.foxx.androidcast.CastSettings;

import org.junit.Test;

public class StreamProtectionNegotiatorTest {
    @Test
    public void autoMapsToNone() {
        assertEquals(CastSettings.StreamProtection.NONE,
                StreamProtectionNegotiator.normalize(CastSettings.StreamProtection.AUTO));
    }

    @Test
    public void bothFec34_agreesWithNack() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.FEC_3_4,
                CastSettings.StreamProtection.FEC_3_4,
                false);
        assertEquals(CastSettings.StreamProtection.FEC_3_4, n.agreed);
        assertTrue(n.nackEnabled);
        assertNull(n.prompt);
    }

    @Test
    public void senderFec34_receiverAuto_usesFec34() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.FEC_3_4,
                CastSettings.StreamProtection.AUTO,
                false);
        assertEquals(CastSettings.StreamProtection.FEC_3_4, n.agreed);
        assertTrue(n.nackEnabled);
    }

    @Test
    public void receiverSide_senderFec34_usesFec34() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.AUTO,
                CastSettings.StreamProtection.FEC_3_4,
                true);
        assertEquals(CastSettings.StreamProtection.FEC_3_4, n.agreed);
        assertTrue(n.nackEnabled);
    }

    @Test
    public void senderNone_receiverAuto_noProtectionWithPrompt() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.NONE,
                CastSettings.StreamProtection.AUTO,
                false);
        assertEquals(CastSettings.StreamProtection.NONE, n.agreed);
        assertNotNull(n.prompt);
    }

    @Test
    public void senderFec34_receiverRsAdvert_usesRs() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.FEC_3_4,
                CastSettings.StreamProtection.FEC_REED_SOLOMON,
                false);
        assertEquals(CastSettings.StreamProtection.FEC_REED_SOLOMON, n.agreed);
        assertNotNull(n.prompt);
    }

    @Test
    public void senderFec34_receiverAuto_usesFec34WithNack() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.FEC_3_4,
                CastSettings.StreamProtection.AUTO,
                false);
        assertEquals(CastSettings.StreamProtection.FEC_3_4, n.agreed);
        assertTrue(n.nackEnabled);
    }

    @Test
    public void senderFec34_receiverAdvertFecNack_usesFec34WithoutNack() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.FEC_3_4,
                CastSettings.StreamProtection.FEC_NACK,
                false);
        assertEquals(CastSettings.StreamProtection.FEC_3_4, n.agreed);
        assertFalse(n.nackEnabled);
    }

    @Test
    public void senderFecNack_receiverAuto_keepsFecNack() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.FEC_NACK,
                CastSettings.StreamProtection.AUTO,
                false);
        assertEquals(CastSettings.StreamProtection.FEC_NACK, n.agreed);
        assertTrue(n.nackEnabled);
    }

    @Test
    public void fecNackWithNackOnly_usesFecNack() {
        StreamProtectionNegotiation n = StreamProtectionNegotiator.negotiate(
                CastSettings.StreamProtection.FEC_NACK,
                CastSettings.StreamProtection.AUTO,
                false);
        assertEquals(CastSettings.StreamProtection.FEC_NACK, n.agreed);
        assertTrue(n.nackEnabled);
    }
}
