package io.cameleer.server.core.runtime;

import io.cameleer.server.core.storage.ArtifactCoordinates;
import io.cameleer.server.core.storage.ArtifactStore;
import org.junit.jupiter.api.Test;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Optional;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class AppServiceUploadTest {

    @Test
    void uploadJarStoresViaArtifactStoreAndRecordsLocator() throws Exception {
        AppRepository appRepo = mock(AppRepository.class);
        AppVersionRepository versionRepo = mock(AppVersionRepository.class);
        ArtifactStore store = mock(ArtifactStore.class);

        UUID appId = UUID.randomUUID();
        UUID versionId = UUID.randomUUID();
        when(appRepo.findById(appId)).thenReturn(Optional.of(
                new App(appId, UUID.randomUUID(), "demo", "Demo", null, null, null)));
        when(versionRepo.findMaxVersion(appId)).thenReturn(2);
        when(store.put(any(), any(InputStream.class), anyLong()))
                .thenReturn("/data/jars/" + appId + "/v3/app.jar");
        when(versionRepo.create(eq(appId), eq(3), anyString(), anyString(), eq("a.jar"), eq(5L)))
                .thenReturn(versionId);
        when(versionRepo.findById(versionId)).thenReturn(Optional.of(
                new AppVersion(versionId, appId, 3, "/data/jars/" + appId + "/v3/app.jar",
                        "deadbeef", "a.jar", 5L, null, null, null)));

        AppService svc = new AppService(appRepo, versionRepo, store, "default");

        byte[] body = "hello".getBytes();
        AppVersion result = svc.uploadJar(appId, "a.jar", new ByteArrayInputStream(body), body.length);

        verify(store).put(eq(new ArtifactCoordinates("default", appId, 3)),
                          any(InputStream.class), eq(5L));
        assertThat(result.version()).isEqualTo(3);
    }
}
