package com.atlassian.bitbucket.scm.cache.web;

import com.atlassian.bitbucket.scm.git.protocol.GitPackets;
import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import static org.junit.Assert.assertArrayEquals;

public class ServiceAdvertisementStrippingOutputStreamTest {

    private static final byte[] PACKET_1 = GitPackets.create("# service=git-upload-pack\n");
    private static final byte[] PACKET_2 = GitPackets.getFlush();
    private static final byte[] PACKET_3 = GitPackets.create("6130a9bc1766379e9a7dee1c96d78b9e45f627f8 HEAD\\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done agent=git/1.8.2.3");

    private ByteArrayOutputStream realOutputStream;
    private ServiceAdvertisementStrippingOutputStream outputStream;

    @Before
    public void setUp() {
        realOutputStream = new ByteArrayOutputStream(1024);
        outputStream = new ServiceAdvertisementStrippingOutputStream(realOutputStream);
    }

    @Test
    public void testWriteAcrossPacketBoundaries() throws IOException {
        byte[] bytes = new byte[PACKET_1.length + 2];
        System.arraycopy(PACKET_1, 0, bytes, 0, PACKET_1.length);
        System.arraycopy(PACKET_2, 0, bytes, PACKET_1.length, 2);

        outputStream.write(bytes);

        bytes = new byte[2 + PACKET_3.length];
        System.arraycopy(PACKET_2, 2, bytes, 0, 2);
        System.arraycopy(PACKET_3, 0, bytes, 2, PACKET_3.length);

        outputStream.write(bytes);

        assertArrayEquals(PACKET_3, realOutputStream.toByteArray());
    }

    @Test
    public void testWriteAllAtOnce() throws IOException {
        byte[] bytes = new byte[PACKET_1.length + PACKET_2.length + PACKET_3.length];

        System.arraycopy(PACKET_1, 0, bytes, 0, PACKET_1.length);
        System.arraycopy(PACKET_2, 0, bytes, PACKET_1.length, PACKET_2.length);
        System.arraycopy(PACKET_3, 0, bytes, PACKET_1.length + PACKET_2.length, PACKET_3.length);

        outputStream.write(bytes);

        assertArrayEquals(PACKET_3, realOutputStream.toByteArray());
    }

    @Test
    public void testWritePacketByPacket() throws IOException {
        outputStream.write(PACKET_1);
        outputStream.write(PACKET_2);
        outputStream.write(PACKET_3);

        assertArrayEquals(PACKET_3, realOutputStream.toByteArray());
    }
}
