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

import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionResultMessage;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;

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

@Slf4j
@Service
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class RedactionResultMessageReceiver {

    ObjectMapper objectMapper;
    DownloadPreparationService downloadPreparationService;


    @SneakyThrows
    @RabbitHandler
    @RabbitListener(queues = MessagingConfiguration.PDFTRON_RESULT_QUEUE)
    public void receive(Message message) throws JsonProcessingException {

        RedactionResultMessage redactionResultMessage = objectMapper.readValue(message.getBody(), RedactionResultMessage.class);

        // This prevents from endless retries oom errors.
        if (message.getMessageProperties().isRedelivered()) {
            throw new AmqpRejectAndDontRequeueException(String.format("Error during last processing of request with downloadId: %s, do not retry.",
                    redactionResultMessage.getDownloadId()));
        }

        receive(redactionResultMessage);
    }


    public void receive(RedactionResultMessage redactionResultMessage) {

        log.info("Received redaction results for downloadId: {} fileId: {}", redactionResultMessage.getDownloadId(), redactionResultMessage.getFileId());

        downloadPreparationService.processingRedactionResultMessage(redactionResultMessage);
    }

}
