package com.elab.spring.intercept;

import com.aliyun.openservices.ons.api.SendResult;
import com.dianping.cat.Cat;
import com.elab.mq.model.MessageModel;
import com.elab.mq.msg.ProducerInterceptor;
import com.elab.redis.CacheTemplate;
import com.jay.monitor.data.client.MonitorSendProducer;
import com.jay.monitor.data.client.utils.MonitorUtils;
import com.jay.monitor.data.core.model.serializable.MQDataDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

/**
 * @Module rmq拦截器
 * @Description 基于缓存实现
 * @Author liukaixiong
 * @Date 2020/12/30 17:25
 */
public class RMQCacheProducerInterceptor implements ProducerInterceptor {

    /**
     * 所有客户端共用这一个唯一编号
     */
    private String defaultPrefix = "RMQProducer:index";

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private CacheTemplate cacheTemplate;

    @Override
    public boolean check(MessageModel messageModel, String groupName) {
        // 由于多个客户端发送，如果区分开的话就得维护多个
        String cacheKey = getCacheKey();
        Long producerId = cacheTemplate.string().increment(cacheKey, 1);
        messageModel.setProducerId(producerId.toString());
        return true;
    }

    @Override
    public void success(MessageModel messageModel, String groupName, SendResult result) {
        sendMonitorData(messageModel, 1);
        logger.debug("业务处理成功,携带的消息唯一编号:" + messageModel.getProducerId());
    }

    @Override
    public void error(MessageModel messageModel, String groupName, Throwable e) {
        sendMonitorData(messageModel, -1);
        logger.debug("业务处理失败,携带的消息唯一编号:" + messageModel.getProducerId());
    }

    private void sendMonitorData(MessageModel data, Integer status) {
        String content = (String) data.getObject(String.class);
        MQDataDTO mqDataDTO = MonitorUtils.builderProducerRMQDataDTO(data.getTopic(), data.getKey(), data.getTag(), data.getMsgID(), content, status);

        builderRemoteId(data, mqDataDTO);

        MonitorSendProducer.sendMsg(data.getTopic(), mqDataDTO);
    }

    /**
     * 构建远程编号,留下相应线索
     *
     * @param data
     * @param mqDataDTO
     */
    private void builderRemoteId(MessageModel data, MQDataDTO mqDataDTO) {
        ///////////////// 上下文链路编号 ////////////////////
        String rootId = data.getUserProperties(Cat.Context.ROOT);
        String parentId = data.getUserProperties(Cat.Context.PARENT);

        mqDataDTO.setParentLogId(parentId);
        mqDataDTO.setRootLogId(rootId);
        mqDataDTO.setLogId(parentId);

        /////////////////// 默认的关键索引线索 ///////////////////////
        if (mqDataDTO.getGroupKeyName() == null) {
            mqDataDTO.setGroupKeyName(data.getKey());
        }

        if (mqDataDTO.getGroupName() == null) {
            mqDataDTO.setGroupName(data.getModuleName());
        }

        if (mqDataDTO.getDataId() == null) {
            mqDataDTO.setDataId(data.getProducerId());
        }

        if (mqDataDTO.getSourceTime() == null) {
            mqDataDTO.setSourceTime(new Date());
        }

    }

    private String getCacheKey() {
        return defaultPrefix;
    }
}
