package cn.ibizlab.core.extensions.util;

import cn.ibizlab.core.extensions.domain.EngineMQMsg;
import cn.ibizlab.core.extensions.domain.LocalMsgEvent;
import cn.ibizlab.core.extensions.domain.ResultsMQMsg;
import cn.ibizlab.core.extensions.domain.SqlResultsMQMsg;
import cn.ibizlab.core.message.DstRocketMQTemplate;
import cn.ibizlab.core.rule.domain.ExecResult;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bytecode.Throw;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;

/**
 * MQ默认发送消息服务
 */
@Slf4j
@Service
@ConditionalOnExpression("(${rocketmq.producer.enabled:false})||(${rocketmq.consumer.enabled:false})")
public class DefaultMQProducerService implements MsgProducerService{

    @Value("${rocketmq.producer.ruleEngineTopic:DSTMSG}")
    private String ruleEngineTopic;

    @Value("${rocketmq.producer.resultsTopic:DSTRESULTSMSG}")
    private String resultsTopic;

    @Autowired
    @Lazy
    DstRocketMQTemplate dstRocketMQTemplate;



    @Override
    public void sendEngineMsg(EngineMQMsg engineMQMsg)  {
        String msg = JSON.toJSONString(engineMQMsg);
        log.trace(String.format("sendEngineMsg:%1$s", msg));
        dstRocketMQTemplate.asyncSendOrderly(ruleEngineTopic+":Engine",msg, DigestUtils.md5DigestAsHex(msg.getBytes()),new SendCallback(){
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("引擎消息发送响应：" + sendResult.toString());
            }

            @Override
            public void onException(Throwable throwable) {
                throwable.printStackTrace();
            }

        });

    }

    @Override
    public void sendBuildMsg(EngineMQMsg engineMQMsg) {
        String msg = JSON.toJSONString(engineMQMsg);
        log.trace(String.format("sendBuildMsg:%1$s", msg));
        dstRocketMQTemplate.asyncSendOrderly(ruleEngineTopic+":Build",msg, DigestUtils.md5DigestAsHex(msg.getBytes()),new SendCallback(){
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("构建消息发送响应：" + sendResult.toString());
            }

            @Override
            public void onException(Throwable throwable) {
                throwable.printStackTrace();
            }

        });
    }

    @Override
    public void sendResultsMsg(ResultsMQMsg resultsMQMsg) throws InterruptedException, RemotingException, MQClientException, MQBrokerException  {
        String msg = JSON.toJSONString(resultsMQMsg);
        log.trace(String.format("sendResultsMsg:%1$s", msg));
        dstRocketMQTemplate.asyncSendOrderly(resultsTopic+":default",msg, DigestUtils.md5DigestAsHex(msg.getBytes()),new SendCallback(){
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("结果消息发送响应：" + sendResult.toString());
            }

            @Override
            public void onException(Throwable throwable) {
                throwable.printStackTrace();
            }

        });

    }

    @Override
    public void sendSqlResultsMsg(SqlResultsMQMsg resultsMQMsg) throws Exception {
        String msg = JSON.toJSONString(resultsMQMsg);
        log.trace(String.format("sendSqlResultsMsg:%1$s", msg));
        dstRocketMQTemplate.asyncSendOrderly(resultsTopic+":SqlResult",msg, DigestUtils.md5DigestAsHex(msg.getBytes()),new SendCallback(){
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("SqlResultsMsg结果消息发送响应：" + sendResult.toString());
            }

            @Override
            public void onException(Throwable throwable) {
                throwable.printStackTrace();
            }

        });

    }

    @Override
    public void sendRuleResultsMsg(String topic, String tags, List<ExecResult> listExecResultMsg){
        try {
            String msg = JSON.toJSONString(listExecResultMsg);
            log.trace(String.format("sendRuleResultsMsg:%1$s", msg));
            dstRocketMQTemplate.asyncSendOrderly(topic+":"+tags,msg, DigestUtils.md5DigestAsHex(msg.getBytes()),new SendCallback(){
                @Override
                public void onSuccess(SendResult sendResult) {
                    log.info("规则结果MQ主题：topic: {}, tags: {},消息发送响应 {}：", topic,tags,sendResult.toString());
                }

                @Override
                public void onException(Throwable throwable) {
                    throwable.printStackTrace();
                }

            });
        } catch (Exception e) {
            e.printStackTrace();
            log.error("规则结果MQ主题：topic: {},tags: {},消息发送异常MQClientException: {}：", topic,tags,e);
        }
    }
}
