package com.liquidnet.service.consumer.base.receiver;

import com.liquidnet.service.base.constant.MQConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.stream.StreamListener;

/**
 * 公共的业务队列消息监听器，具体消费逻辑通过`consumerMessageHandler`实现
 *
 * @author zhanggb
 * Created by IntelliJ IDEA at 2022/3/31
 */
@Slf4j
public abstract class AbstractBizRedisReceiver implements StreamListener<String, MapRecord<String, String, String>> {
    @Autowired
    public StringRedisTemplate stringRedisTemplate;

    @Override
    public void onMessage(MapRecord<String, String, String> message) {
        String redisStreamKey = this.getRedisStreamKey();
        log.debug("CONSUMER MSG_BIZ[streamKey:{},messageId:{},stream:{},body:{}]", redisStreamKey, message.getId(), message.getStream(), message.getValue());
        boolean result = this.consumerMessageHandler(message.getValue().get(MQConst.QUEUE_MESSAGE_KEY));
        log.info("CONSUMER MSG_BIZ RESULT:{} ==> [{}]MESSAGE_ID:{}", result, redisStreamKey, message.getId());

        try {
            stringRedisTemplate.opsForStream().acknowledge(getRedisStreamGroup(), message);
        } catch (Exception e) {
            log.error("#CONSUMER MSG_BIZ EX_ACK ==> [{}]RESULT:{},MESSAGE:{}", redisStreamKey, result, message.getValue(), e);
        }
        try {
            stringRedisTemplate.opsForStream().delete(redisStreamKey, message.getId());
        } catch (Exception e) {
            log.error("#CONSUMER MSG_BIZ EX_DEL ==> [{}]RESULT:{},MESSAGE:{}", redisStreamKey, result, message.getValue(), e);
        }
    }

    protected abstract boolean consumerMessageHandler(String msg);

    protected abstract String getRedisStreamKey();

    protected abstract String getRedisStreamGroup();
}