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

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

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

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

import com.iqser.red.service.peristence.v1.server.integration.client.FileClient;
import com.iqser.red.service.peristence.v1.server.integration.client.ReanalysisClient;
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.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.knecon.fforesight.tenantcommons.TenantContext;

public class ReanalysisTest extends AbstractPersistenceServerServiceTest {

    @Autowired
    private FileTesterAndProvider fileTesterAndProvider;

    @Autowired
    private DossierTesterAndProvider dossierTesterAndProvider;

    @Autowired
    private ReanalysisClient reanalysisClient;

    @Autowired
    private FileClient fileClient;

    @Autowired
    private FileRepository fileRepository;


    @Test
    public void testReanalysis() {

        var dossier = dossierTesterAndProvider.provideTestDossier();

        var file = fileTesterAndProvider.testAndProvideFile(dossier);

        var loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isNotEqualTo(ProcessingStatus.PROCESSED);

        reanalysisClient.ocrDossier(dossier.getId());
        loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isNotEqualTo(ProcessingStatus.PROCESSED);
        resetProcessingStatus(file);

        reanalysisClient.ocrDossier(dossier.getId());
        loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.OCR_PROCESSING_QUEUED);
        resetProcessingStatus(file);

        reanalysisClient.ocrFile(dossier.getId(), file.getId(), true);
        loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.OCR_PROCESSING_QUEUED);
        resetProcessingStatus(file);

        reanalysisClient.ocrFiles(dossier.getId(), Set.of(file.getId()));
        loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.OCR_PROCESSING_QUEUED);
        resetProcessingStatus(file);

        reanalysisClient.reanalyzeFilesForDossier(dossier.getId(), List.of(file.getId()), true);
        loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.FULL_PROCESSING);
        resetProcessingStatus(file);

        reanalysisClient.reanalyzeDossier(dossier.getId(), true);
        loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.FULL_PROCESSING);
        resetProcessingStatus(file);

    }


    private void resetProcessingStatus(FileStatus file) {

        TenantContext.setTenantId("redaction");

        fileRepository.findById(file.getId()).ifPresent(savedFile -> {

            savedFile.setOcrStartTime(null);
            savedFile.setProcessingStatus(ProcessingStatus.PROCESSED);
            fileRepository.save(savedFile);

        });

        var loadedFile = fileClient.getFileStatus(file.getDossierId(), file.getId());
        assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.PROCESSED);
    }

}
