package com.iqser.red.service.persistence.management.v1.processor.service.job;

import static com.iqser.red.service.persistence.management.v1.processor.utils.TenantUtils.isTenantReadyForPersistence;

import java.util.Set;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.management.v1.processor.model.AnalysisFlagCalculationMessage;
import com.iqser.red.service.persistence.management.v1.processor.model.FileIdentifier;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.knecon.fforesight.tenantcommons.TenantContext;
import com.knecon.fforesight.tenantcommons.TenantProvider;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@DisallowConcurrentExecution
/*
 * This Job checks if there might be a change in the analysis flags and then schedules a flag calculation using a queue to balance the load.
 */ public class AnalysisFlagCalculationSchedulerJob implements Job {

    FileStatusService fileStatusService;
    RabbitTemplate rabbitTemplate;
    TenantProvider tenantProvider;


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        tenantProvider.getTenants()
                .forEach(tenant -> {
                    if (isTenantReadyForPersistence(tenant)) {
                        TenantContext.setTenantId(tenant.getTenantId());
                        log.debug("Detecting Files for analysis flag calculation. Tenant: {}", tenant.getDisplayName());

                        Set<FileIdentifier> fileIdentifiers = fileStatusService.getFileIdentifiersWhereAnalysisFlagCalculationIsRequired();

                        log.debug("Found {} files which require analysis flag calculation. Tenant: {}", fileIdentifiers.size(), tenant.getDisplayName());

                        fileIdentifiers.forEach(fileIdentifier -> rabbitTemplate.convertAndSend(MessagingConfiguration.ANALYSIS_FLAG_CALCULATION_REQUEST_EXCHANGE,
                                                                                                TenantContext.getTenantId(),
                                                                                                new AnalysisFlagCalculationMessage(fileIdentifier.dossierId(),
                                                                                                                                   fileIdentifier.fileId())));
                        TenantContext.clear();
                    }
                });
    }

}
