package com.foxx.androidcast.network.transport;

/*********************************************************************
 * FecProtectionEngineShardTest.java
 * Created at: Mon 18 May 2026 14:25:02 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class FecProtectionEngineShardTest
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (3 commits, 63 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	3bdb27efe68e2c9216ef648a9fe671ccdac8774a6a74d45baabed0bd8b097d9f
**********************************************************************/
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.foxx.androidcast.network.CastProtocol;
import com.foxx.androidcast.network.transport.fec.FecEncodedGroup;
import com.foxx.androidcast.network.transport.fec.ProtectionEnvelope;

import org.junit.Test;

public class FecProtectionEngineShardTest {
    @Test
    public void largePayload_usesMoreSmallerShards() throws Exception {
        TransportLossStats stats = new TransportLossStats();
        FecProtectionEngine fec = new FecProtectionEngine(
                ProtectionEnvelope.MODE_FEC_34, 4, 3, stats);
        byte[] payload = new byte[180_000];
        FecEncodedGroup group = fec.encodeGroup(payload);
        assertEquals(16, group.dataShards);
        assertEquals(8, group.parityShards);
        assertEquals(24, group.totalShards());
        int shardBytes = group.shards[0].length;
        assertTrue(shardBytes < 16_000);
    }

    @Test
    public void encodeAndDecodeShards_viaEngine() throws Exception {
        TransportLossStats stats = new TransportLossStats();
        FecProtectionEngine fec = new FecProtectionEngine(
                ProtectionEnvelope.MODE_FEC_34, 4, 3, stats);
        byte[] payload = "fec-shard-engine-roundtrip".getBytes();
        FecEncodedGroup group = fec.encodeGroup(payload);
        assertEquals(7, group.totalShards());

        int baseId = 100;
        FecProtectionEngine.ShardDecodeResult decoded = null;
        for (int i = 0; i < group.totalShards(); i++) {
            if (i == 3) {
                continue;
            }
            byte[] wire = fec.encodeShardWire(group, baseId, i);
            FecProtectionEngine.ShardDecodeResult r =
                    fec.onInboundShard(CastProtocol.MSG_VIDEO_FRAME, wire);
            if (r.status == FecProtectionEngine.ShardDecodeResult.Status.OK) {
                decoded = r;
                break;
            }
        }
        assertNotNull(decoded);
        assertArrayEquals(payload, decoded.payload);
    }
}
