package com.bonus.mq.rabbit.tx;

import cn.hutool.core.collection.CollUtil;
import com.bonus.mq.MQTemplate;
import com.bonus.mq.rabbit.RabbitPropertiesExt;
import com.bonus.mq.tx.MQTxCheckComposite;
import com.bonus.mq.tx.TxMessageManager;
import com.xxl.job.core.handler.IJobHandler;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TxCheckJobHandler extends IJobHandler {
   private static final Logger log = LoggerFactory.getLogger(TxCheckJobHandler.class);
   private final MQTxCheckComposite rocketMQTxCheckComposite;
   private final TxMessageManager txMessageManager;
   private final MQTemplate mqTemplate;
   private final ThreadPoolExecutor poolExecutor;

   public TxCheckJobHandler(TxMessageManager txMessageManager, MQTxCheckComposite rocketMQTxCheckComposite, MQTemplate mqTemplate) {
      this.poolExecutor = new ThreadPoolExecutor(1, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue(1000), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
      this.txMessageManager = txMessageManager;
      this.rocketMQTxCheckComposite = rocketMQTxCheckComposite;
      this.mqTemplate = mqTemplate;
   }

   public void execute() throws Exception {
      List<RabbitPropertiesExt.RabbitMessage> messages = this.txMessageManager.failedMessage();
      if (!CollUtil.isEmpty(messages)) {
         Iterator var2 = messages.iterator();

         while(var2.hasNext()) {
            RabbitPropertiesExt.RabbitMessage message = (RabbitPropertiesExt.RabbitMessage)var2.next();
            this.poolExecutor.execute(() -> {
               try {
                  MessageExt messageExt = new MessageExt();
                  String[] topicAndTag = message.getRoutingKey().split(":", 2);
                  messageExt.setTopic(topicAndTag[0]);
                  if (topicAndTag.length > 1) {
                     messageExt.setTags(topicAndTag[1]);
                  }

                  messageExt.setBody(message.getPayload().getBytes(StandardCharsets.UTF_8));

                  LocalTransactionState transactionState;
                  try {
                     transactionState = this.rocketMQTxCheckComposite.checkLocalTransactionState(messageExt);
                  } catch (Throwable var7) {
                     log.error("Exception occurred while localTxState check", var7);
                     return;
                  }

                  if (transactionState == LocalTransactionState.COMMIT_MESSAGE) {
                     if (message.getDelay() != null) {
                        int time2Delay = (int) LocalDateTime.now().until(message.getCreateTime().plus(message.getDelay(), ChronoUnit.MILLIS), ChronoUnit.MILLIS);
                        if (time2Delay > 0L) {
                           this.mqTemplate.sendDelay(message.getRoutingKey(), message.getPayload(), time2Delay);
                           this.txMessageManager.afterSendSuccess(message.getId());
                           return;
                        }

                        this.mqTemplate.send(message.getRoutingKey(), message.getPayload());
                        this.txMessageManager.afterSendSuccess(message.getId());
                        return;
                     }

                     this.mqTemplate.send(message.getRoutingKey(), message.getPayload());
                     this.txMessageManager.afterSendSuccess(message.getId());
                     return;
                  }

                  if (transactionState == LocalTransactionState.ROLLBACK_MESSAGE) {
                     this.txMessageManager.afterRollback(message.getId());
                  }
               } catch (Throwable var8) {
               }

            });
         }

      }
   }

   public TxCheckJobHandler(final MQTxCheckComposite rocketMQTxCheckComposite, final TxMessageManager txMessageManager, final MQTemplate mqTemplate) {
      this.poolExecutor = new ThreadPoolExecutor(1, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue(1000), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
      this.rocketMQTxCheckComposite = rocketMQTxCheckComposite;
      this.txMessageManager = txMessageManager;
      this.mqTemplate = mqTemplate;
   }
}
