package tech.easyflow.common.mq.redis;

import org.springframework.data.redis.connection.stream.StreamRecords;
import org.springframework.data.redis.core.StringRedisTemplate;
import tech.easyflow.common.mq.core.MQDeadLetterHandler;
import tech.easyflow.common.mq.core.MQDeadLetterService;
import tech.easyflow.common.mq.core.MQMessage;
import tech.easyflow.common.mq.core.MQMessageConverter;
import tech.easyflow.common.mq.exception.MQException;

import java.util.List;
import java.util.Map;

public class RedisMQDeadLetterService implements MQDeadLetterService {

    private final StringRedisTemplate stringRedisTemplate;
    private final MQMessageConverter messageConverter;
    private final RedisStreamKeySupport keySupport;
    private final List<MQDeadLetterHandler> handlers;

    public RedisMQDeadLetterService(StringRedisTemplate stringRedisTemplate,
                                    MQMessageConverter messageConverter,
                                    RedisStreamKeySupport keySupport,
                                    List<MQDeadLetterHandler> handlers) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.messageConverter = messageConverter;
        this.keySupport = keySupport;
        this.handlers = handlers;
    }

    @Override
    public void deadLetter(MQMessage message, String reason) {
        if (message == null) {
            return;
        }
        message.getHeaders().put("deadLetterReason", reason == null ? "" : reason);
        String deadLetterKey = keySupport.deadLetterKey(message.getTopic());
        if (stringRedisTemplate.opsForStream().add(
                StreamRecords.string(Map.of("payload", messageConverter.serialize(message))).withStreamKey(deadLetterKey)
        ) == null) {
            throw new MQException("写入死信流失败");
        }
        for (MQDeadLetterHandler handler : handlers) {
            if (handler.supports(message.getTopic())) {
                handler.handle(message, reason);
            }
        }
    }
}
