package com.atlassian.stash.internal.repository.sync.auto;

import com.atlassian.bitbucket.repository.RefChange;
import com.atlassian.bitbucket.repository.Repository;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.io.*;
import java.util.List;

import static com.atlassian.stash.internal.repository.sync.RefSyncTestUtils.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class AutoRefSyncRequestTest {

    @Mock(name = "repository")
    private Repository repository;
    @Mock(name = "upstream")
    private Repository upstream;

    @Before
    public void setup() {
        when(repository.getId()).thenReturn(22);
        when(upstream.getId()).thenReturn(2);
    }

    @Test
    public void testExternalization() throws Exception {
        RefChange add = add("refs/heads/add", "eea09bf8ffde47ea6ef1a092c4a9e8610e6b01f7");
        RefChange delete = delete("refs/heads/delete", "96a411f7a230682e683b96a1b6a4b410644d467d");
        RefChange update = update("refs/heads/test", "e1c5a8e1ad0f5179973d23f76fbafd065e827699",
                "2c37e22f88336b23077c3f97d8eca82945d302d8");
        AutoRefSyncRequest original = requestFor(repository, upstream, add, update, delete);

        PipedInputStream pipe = new PipedInputStream(32768);
        PipedOutputStream pipeOut = new PipedOutputStream(pipe);

        ObjectOutput outputStream = new ObjectOutputStream(pipeOut);
        outputStream.writeObject(original);
        outputStream.flush();

        ObjectInput input = new ObjectInputStream(pipe);
        AutoRefSyncRequest read = (AutoRefSyncRequest) input.readObject();

        assertSame(original.getOperation(), read.getOperation());
        assertEquals(original.getRepositoryId(), read.getRepositoryId());
        assertEquals(original.getUpstreamId(), read.getUpstreamId());
        assertEquals(original.getUserId(), read.getUserId());

        List<RefChange> originalChanges = original.getRefChanges();
        List<RefChange> readChanges = read.getRefChanges();
        assertEquals(originalChanges.size(), readChanges.size());
        for (int i = 0; i < originalChanges.size(); ++i) {
            RefChange originalChange = originalChanges.get(i);
            RefChange readChange = readChanges.get(i);

            assertEquals("refChange[" + i + "].fromHash", originalChange.getFromHash(), readChange.getFromHash());
            assertEquals("refChange[" + i + "].refId", originalChange.getRefId(), readChange.getRefId());
            assertEquals("refChange[" + i + "].toHash", originalChange.getToHash(), readChange.getToHash());
            assertSame("refChange[" + i + "].type", originalChange.getType(), readChange.getType());
        }
    }
}