package cn.yunzhixue.ability.center.examsprint.infrastructure.report.storage;

import cn.yunzhixue.ability.center.examsprint.contracts.report.ExamSprintReportType;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import org.junit.jupiter.api.Test;

import java.net.URI;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneOffset;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

class AzureBlobExamSprintReportStorageTest {

    private static final Clock FIXED_CLOCK = Clock.fixed(Instant.parse("2026-01-03T08:00:00Z"), ZoneOffset.UTC);

    @Test
    void generateDownloadUrlReturnsApplicationDownloadEndpoint() {
        BlobContainerClient containerClient = mock(BlobContainerClient.class);
        AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(containerClient, FIXED_CLOCK);

        URI downloadUrl = storage.generateDownloadUrl(
                "exam-sprint-reports/outlook/report-123/exam-sprint-outlook-report-report-123.pdf",
                Duration.ofMinutes(15));

        assertThat(downloadUrl).isEqualTo(URI.create("/api/exam-sprint/reports/report-123/download"));
        verifyNoInteractions(containerClient);
    }

    @Test
    void uploadWritesUploadedAtMetadataFromInjectedClock() {
        BlobContainerClient containerClient = mock(BlobContainerClient.class);
        BlobClient blobClient = mock(BlobClient.class);
        when(containerClient.getBlobClient("exam-sprint-reports/outlook/report-123/file.pdf")).thenReturn(blobClient);
        AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(containerClient, FIXED_CLOCK);

        storage.upload(
                "report-123",
                ExamSprintReportType.OUTLOOK,
                "file.pdf",
                new byte[]{1, 2, 3},
                Instant.parse("2026-01-10T00:00:00Z"));

        verify(blobClient).setMetadata(argThat(metadata ->
                "report-123".equals(metadata.get("reportId"))
                        && "OUTLOOK".equals(metadata.get("reportType"))
                        && "2026-01-10T00:00:00Z".equals(metadata.get("expiresAt"))
                        && FIXED_CLOCK.instant().toString().equals(metadata.get("uploadedAt"))));
    }
}
