package com.atlassian.bitbucket.internal.mirroring.upstream;

import com.atlassian.bitbucket.audit.AuditEntry;
import com.atlassian.bitbucket.audit.AuditEntryBuilder;
import com.atlassian.bitbucket.internal.mirroring.SimpleMirroringRequest;
import com.atlassian.bitbucket.internal.mirroring.MirroringRequestState;
import com.atlassian.bitbucket.mirroring.upstream.MirroringRequestAcceptedEvent;
import com.atlassian.bitbucket.mirroring.upstream.MirroringRequestCreatedEvent;
import org.junit.Before;
import org.junit.Test;

import java.net.URI;

import static com.atlassian.bitbucket.JsonTestUtils.assertJsonContains;
import static com.atlassian.bitbucket.internal.mirroring.MirroringRequestState.*;
import static org.junit.Assert.assertEquals;

public class MirroringRequestEventConverterTest {
    private static URI DESCRIPTOR_URI = URI.create("https://example.com/descriptor");
    private static String BASE_URL = "https://bitbucket-eu.example.com";

    private AuditEntryBuilder builder;
    private MirroringRequestEventConverter converter;
    private SimpleMirroringRequest request;

    @Before
    public void setUp() throws Exception {
        builder = new AuditEntryBuilder();
        converter = new MirroringRequestEventConverter();
    }

    @Test
    public void testRequestAccepted() {
        request = newRequest(ACCEPTED);

        AuditEntry entry = converter.convert(new MirroringRequestAcceptedEvent(this, request), this.builder);
        assertAuditEntry(entry, ACCEPTED, MirroringRequestAcceptedEvent.class.getSimpleName(), entry.getAction());
    }

    @Test
    public void testRequestRejected() {
        request = newRequest(REJECTED);

        AuditEntry entry = converter.convert(new MirroringRequestCreatedEvent(this, request), this.builder);
        assertAuditEntry(entry, REJECTED, MirroringRequestCreatedEvent.class.getSimpleName(), entry.getAction());
    }

    @Test
    public void testRequestCreated() {
        request = newRequest(PENDING);

        AuditEntry entry = converter.convert(new MirroringRequestCreatedEvent(this, request), this.builder);
        assertAuditEntry(entry, PENDING, MirroringRequestCreatedEvent.class.getSimpleName(), entry.getAction());
    }

    private SimpleMirroringRequest newRequest(MirroringRequestState state) {
        return new SimpleMirroringRequest.Builder()
            .id(0)
            .addonDescriptor(DESCRIPTOR_URI)
            .mirrorBaseUrl(BASE_URL)
            .mirrorServer("mirror-id", "mirror-name")
            .product("Bitbucket", "4.0.0")
            .state(state)
            .build();
    }

    private void assertAuditEntry(AuditEntry entry, MirroringRequestState state, String simpleName, String action) {
        assertEquals(simpleName, action);

        String details = entry.getDetails();
        assertJsonContains(details, "request.id", "0");
        assertJsonContains(details, "request.addonDescriptorUri", DESCRIPTOR_URI.toASCIIString());
        assertJsonContains(details, "request.mirrorBaseUrl", BASE_URL);
        assertJsonContains(details, "request.mirrorId", "mirror-id");
        assertJsonContains(details, "request.mirrorName", "mirror-name");
        assertJsonContains(details, "request.productType", "Bitbucket");
        assertJsonContains(details, "request.productVersion", "4.0.0");
        assertJsonContains(details, "request.state", state.getId());
    }
}
