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

import java.io.IOException;

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.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue;

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

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

    private static final String LINE_SEPARATOR = System.lineSeparator();

    ObjectMapper objectMapper;
    DownloadStatusPersistenceService downloadStatusPersistenceService;
    DownloadPreparationService downloadPreparationService;


    @RabbitHandler
    @RabbitListener(queues = MessagingConfiguration.PDFTRON_DLQ)
    public void receive(Message message) throws IOException {

        // Since we receive different message types here, we do not convert to an object here;
        // We just assume that the message contains a downloadId.
        JsonNode jsonNode = objectMapper.readTree(message.getBody());
        final String downloadId;
        final String fileId;
        try {
            downloadId = jsonNode.findValue("downloadId").asText();

        } catch (Exception e) {
            log.warn("Received a message in the " + MessagingConfiguration.PDFTRON_DLQ + " that contains no downloadId" + LINE_SEPARATOR + "{}", jsonNode.asText());
            throw new RuntimeException(e);
        }

        try {
            fileId = jsonNode.findValue("fileId").asText();
            var unapproved = jsonNode.findValue("unapprovedFile");
            log.info("Received a dead message with downloadId: {}, fileId: {} check for retry", downloadId, fileId);
            downloadPreparationService.checkForRetryProcess(downloadId, fileId, unapproved.asBoolean());

        } catch (Exception e) {
            log.info("Received a dead message with downloadId: {}, updating the download as failed", downloadId);
            downloadStatusPersistenceService.updateStatus(downloadId, DownloadStatusValue.FAILED);
        }
    }

}
