package org.ssssssss.magicapi.rocketmq.product;

import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.ssssssss.magicapi.core.annotation.MagicModule;
import org.ssssssss.magicapi.rocketmq.service.RocketMqService;
import org.ssssssss.script.annotation.Comment;

/**
 * rocketMq模块
 *
 * @author zzy
 */
@MagicModule("rocketMq")
public class RocketMqModule {

    private final RocketMQTemplate rocketMQTemplate;

    private final RocketMqService rocketMqService;

    public RocketMqModule(RocketMQTemplate rocketMQTemplate, RocketMqService rocketMqService) {
        this.rocketMQTemplate = rocketMQTemplate;
        this.rocketMqService = rocketMqService;
    }

    /**
     * 同步发送实体对象消息
     * 可靠同步发送：同步发送是指消息发送方发出数据后，会在收到接收方发回响应之后才发下一个数据包的通讯方式；
     * 特点：速度快；有结果反馈；数据可靠；
     * 应用场景：应用场景非常广泛，例如重要通知邮件、报名短信通知、营销短信系统等；
     */
    @Comment("同步发送实体对象消息")
    public boolean send(String topic, String tag, Object msg) {
        rocketMqService.beforeProduce(topic, tag, msg);
        SendResult sendResult = rocketMQTemplate.syncSend(topic + ":" + tag, msg);
        if (sendResult.getSendStatus() != SendStatus.SEND_OK) {
            rocketMqService.failProduce(topic, tag, msg);
            return false;
        }
        rocketMqService.afterProduce(topic, tag, msg);
        return true;
    }

    /**
     * 异步发送消息
     * 可靠异步发送：发送方发出数据后，不等接收方发回响应，接着发送下个数据包的通讯方式；
     * 特点：速度快；有结果反馈；数据可靠；
     * 应用场景：异步发送一般用于链路耗时较长,对 rt响应时间较为敏感的业务场景,例如用户视频上传后通知启动转码服务,转码完成后通知推送转码结果等；
     *
     * @param msg
     * @return
     */
    @Comment("异步发送消息")
    public boolean asyncSend(String topic, String tag, Object msg) {
        rocketMqService.beforeProduce(topic, tag, msg);
        rocketMQTemplate.asyncSend(topic + ":" + tag, msg, new SendCallback() {
            @Override
            public void onSuccess(SendResult var1) {
                // 成功回调
                rocketMqService.afterProduce(topic, tag, msg);
            }

            @Override
            public void onException(Throwable var1) {
                // 失败回调
                rocketMqService.failProduce(topic, tag, msg);
            }
        });
        return true;
    }

    /**
     * 单向发送
     * 单向发送：只负责发送消息，不等待服务器回应且没有回调函数触发，即只发送请求不等待应答；此方式发送消息的过程耗时非常短，一般在微秒级别；
     * 特点：速度最快，耗时非常短，毫秒级别；无结果反馈；数据不可靠，可能会丢失；
     * 应用场景：适用于某些耗时非常短，但对可靠性要求并不高的场景，例如日志收集；
     *
     * @return
     */
    @Comment("单向发送")
    public boolean sendOneway(String topic, String tag, Object msg) {
        rocketMqService.beforeProduce(topic, tag, msg);
        rocketMQTemplate.sendOneWay(topic + ":" + tag, msg);
        rocketMqService.afterProduce(topic, tag, msg);
        return true;
    }


}
