package com.iqser.red.service.peristence.v1.server.integration.tests;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionResultMessage;
import com.iqser.red.service.peristence.v1.server.integration.client.DownloadClient;
import com.iqser.red.service.peristence.v1.server.integration.client.FileClient;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.service.FileTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.service.UserProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.management.v1.processor.model.DownloadJob;
import com.iqser.red.service.persistence.management.v1.processor.service.download.DownloadMessageReceiver;
import com.iqser.red.service.persistence.management.v1.processor.service.download.DownloadPreparationService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.PrepareDownloadRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.PrepareDownloadWithOptionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.RemoveDownloadRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
import com.iqser.red.service.redaction.report.v1.api.model.ReportResultMessage;
import com.knecon.fforesight.tenantcommons.TenantContext;

import feign.FeignException;
import lombok.SneakyThrows;

public class DownloadTest extends AbstractPersistenceServerServiceTest {

    @Autowired
    private FileTesterAndProvider fileTesterAndProvider;

    @Autowired
    private DossierTesterAndProvider dossierTesterAndProvider;

    @Autowired
    private DownloadClient downloadClient;

    @Autowired
    private FileClient fileClient;

    @Autowired
    private DownloadMessageReceiver downloadMessageReceiver;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private UserProvider userProvider;

    @Autowired
    private DownloadPreparationService downloadPreparationService;


    @Test
    @SneakyThrows
    public void testDownload() {

        var dossier = dossierTesterAndProvider.provideTestDossier();

        var file = fileTesterAndProvider.testAndProvideFile(dossier);
        var file2 = fileTesterAndProvider.testAndProvideFile(dossier, "file2");

        fileTesterAndProvider.markFileAsProcessed(file2.getFileId());

        fileClient.setStatusApproved(dossier.getId(), file2.getId());
        var file22 = fileClient.getFileStatus(dossier.getId(), file2.getId());
        assertThat(file22.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);

        try {
            downloadClient.prepareDownload(PrepareDownloadRequest.builder().dossierId(dossier.getId()).fileIds(List.of(file.getId(), file2.getId())).build());
        } catch (FeignException e) {
            assertThat(e.status()).isEqualTo(400);
        }

        var downloads = downloadClient.prepareDownload(PrepareDownloadWithOptionRequest.builder()
                .downloadFileTypes(Set.of(DownloadFileType.ORIGINAL))
                .dossierId(dossier.getId())
                .fileIds(List.of(file2.getId()))
                .build());

        downloadMessageReceiver.receive(new DownloadJob(userProvider.getUserId(), downloads.getStorageId()));
        var reportInfoId = downloads.getStorageId().substring(0, downloads.getStorageId().length() - 3) + "/REPORT_INFO.json";
        storageService.storeJSONObject(TenantContext.getTenantId(), reportInfoId, new ArrayList<>());

        downloadPreparationService.createDownload(ReportResultMessage.builder().downloadId(downloads.getStorageId()).build());

        downloadPreparationService.processingRedactionResultMessage(RedactionResultMessage.builder().downloadId(downloads.getStorageId()).dossierId(dossier.getId()).fileId(file.getId()).build());
        downloadPreparationService.processingRedactionResultMessage(RedactionResultMessage.builder().downloadId(downloads.getStorageId()).dossierId(dossier.getId()).fileId(file2.getId()).build());

        var statuses = downloadClient.getDownloadStatus();
        assertThat(statuses.getDownloadStatus()).isNotEmpty();
        assertThat(statuses.getDownloadStatus().iterator().next().getLastDownload()).isNull();

        downloadClient.deleteDownloadStatus(new RemoveDownloadRequest(List.of(statuses.getDownloadStatus().iterator().next().getStorageId())));
        statuses = downloadClient.getDownloadStatus();
        assertThat(statuses.getDownloadStatus()).isEmpty();

    }

}
