package org.springblade.common.notify.rocketmq.consumer;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.ons.api.*;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Properties;

/**
 * @author Cai Yihua
 **/
@Slf4j
public class AliyunConsumerProxy implements ConsumerProxy {
    private Consumer consumer = null;

    @Override
    public void startup(Properties properties, MqMessageHandlerHolder mqMessageHandlerHolder) {
        properties.put(PropertyKeyConst.MaxReconsumeTimes, mqMessageHandlerHolder.getMaxRetryTimes());
        consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe(mqMessageHandlerHolder.getTopic(), mqMessageHandlerHolder.getTag(),
                (message, consumeContext) -> {
                    if (message == null) {
                        log.warn("The input message is NULL!!!");
                        return Action.CommitMessage;
                    }

                    try {
                        String messageBody = new String(message.getBody(), StandardCharsets.UTF_8);

                        if (!message.getTopic().equals(mqMessageHandlerHolder.getTopic()) || (!mqMessageHandlerHolder.getTag().equals("*") && !mqMessageHandlerHolder.getTag().contains(message.getTag()))) {
                            log.warn(
                                    "The input message should not be handled by this handler. The message topic is {}, the message tag is {}; The handler topic is {}, the handler tag is {}.",
                                    message.getTopic(), message.getTag(), mqMessageHandlerHolder.getTopic(),
                                    mqMessageHandlerHolder.getTag());
                            return Action.CommitMessage;
                        }

                        MqMessage mqMessage = new MqMessage();
                        mqMessage.setConsumerId(mqMessageHandlerHolder.getConsumerId());
                        mqMessage.setTopic(message.getTopic());
                        mqMessage.setTopic(message.getTag());
                        mqMessage.setMessageId(message.getMsgID());
                        mqMessage.setMessageBody(messageBody);
                        mqMessage.setOriginMessage(JSONObject.toJSONString(message));

                        boolean flag = mqMessageHandlerHolder.getMqMessageHandler().handle(Arrays.asList(mqMessage));
                        log.info("ConsumerId:{}, Topic:{}, Tag:{}, the result of handling message:{}", mqMessageHandlerHolder.getConsumerId(), mqMessageHandlerHolder.getTopic(), mqMessageHandlerHolder.getTag(), flag);

                        // 如果成功，或者当重试次数超过某个阈值则返回成功.
                        if (flag || message.getReconsumeTimes() >= mqMessageHandlerHolder.getMaxRetryTimes()) {
                            return Action.CommitMessage;
                        }

                        return Action.ReconsumeLater;
                    } catch (Exception e) {
                        log.error("consume message error.", e);
                        if (message.getReconsumeTimes() >= mqMessageHandlerHolder.getMaxRetryTimes()) {
                            return Action.CommitMessage;
                        }
                        return Action.ReconsumeLater;
                    }
                });
        consumer.start();
        log.info("Aliyun RocketMQ Consumer Started, Topic:{}, Tag:{}", mqMessageHandlerHolder.getTopic(),
                mqMessageHandlerHolder.getTag());
    }

    @Override
    public void shutdown() {
        if (consumer != null) {
            consumer.shutdown();
            consumer = null;
        }
    }

    @Override
    public boolean isStarted() {
        return consumer != null;
    }
}
