package com.bonus.common.houqin.mq.rocket;

import com.bonus.common.houqin.mq.MQMessageConverter;
import com.bonus.common.houqin.mq.MQProperties;
import com.bonus.common.houqin.mq.mqtt.MqttProperties;
import com.bonus.common.houqin.mq.rocket.mqtt.MqttConfiguration;
import com.bonus.common.houqin.mq.*;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.impl.MQAdminImpl;
import org.apache.rocketmq.client.impl.MQClientAPIImpl;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.remoting.protocol.body.ClusterInfo;
import org.apache.rocketmq.remoting.protocol.body.SubscriptionGroupWrapper;
import org.apache.rocketmq.remoting.protocol.route.BrokerData;
import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.messaging.converter.MessageConverter;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

@Configuration
//@AutoConfigureBefore({MqttConfiguration.class})
public class RocketListenerConfiguration {
   private static final Logger log = LoggerFactory.getLogger(RocketListenerConfiguration.class);
   public static final int TIMEOUT_MILLIS = 10000;
   private final Environment environment;
   private final MessageConverter messageConverter;
   private final MQProperties mqProperties;

   public RocketListenerConfiguration(RocketMQTemplate rocketMQTemplate, MqttProperties mqttProperties, ApplicationContext applicationContext, Environment environment, MQMessageConverter mqMessageConverter, MQProperties mqProperties) throws MQBrokerException, RemotingException, InterruptedException, MQClientException {
      try {
         this.environment = environment;
         this.messageConverter = mqMessageConverter.getMessageConverter();
         this.mqProperties = mqProperties;
         Map<String, String> group_subscription = Maps.newHashMap();
         Set<RocketListenerContainer> listenerContainers = Sets.newHashSet();
         GenericApplicationContext genericApplicationContext = (GenericApplicationContext)applicationContext;
         int counter = 0;
         Map<String, Object> beans = applicationContext.getBeansWithAnnotation(MQMessageListener.class);
         Iterator var12 = beans.values().iterator();

         RocketListenerContainer listenerContainer;
         while(var12.hasNext()) {
            Object bean = var12.next();
            Class<?> clazz = AopProxyUtils.ultimateTargetClass(bean);
            if (!MQListener.class.isAssignableFrom(bean.getClass())) {
               String var10002 = String.valueOf(clazz);
               throw new IllegalStateException(var10002 + " is not instance of " + MQListener.class.getName());
            }

            MQMessageListener annotation = (MQMessageListener)clazz.getAnnotation(MQMessageListener.class);
            String containerBeanName = String.format("%s_%s", RocketListenerContainer.class.getName(), counter++);
            listenerContainer = this.createMQListenerContainer(containerBeanName, bean, annotation);
            String var10000 = listenerContainer.getTopic();
            String nowActualTopic = var10000 + ":" + listenerContainer.getTag();
            String preSubscribe = (String)group_subscription.get(listenerContainer.getConsumerGroup());
            if (preSubscribe != null && !preSubscribe.equals(nowActualTopic)) {
               throw new IllegalArgumentException("Subscription consistency error: " + listenerContainer.getConsumerGroup() + "-> [" + nowActualTopic + "," + preSubscribe + "]");
            }

            group_subscription.put(listenerContainer.getConsumerGroup(), nowActualTopic);
            listenerContainers.add(listenerContainer);
         }

         MQClientAPIImpl mqClient = rocketMQTemplate.getProducer().getDefaultMQProducerImpl().getMqClientFactory().getMQClientAPIImpl();
         ClusterInfo brokerClusterInfo = mqClient.getBrokerClusterInfo(10000L);
         Iterator var24 = brokerClusterInfo.getBrokerAddrTable().values().iterator();

         Iterator var28;
         while(var24.hasNext()) {
            BrokerData brokerData = (BrokerData)var24.next();
            var28 = brokerData.getBrokerAddrs().values().iterator();

            while(var28.hasNext()) {
               String brokerAddr = (String)var28.next();
               SubscriptionGroupWrapper allSubscriptionGroup = mqClient.getAllSubscriptionGroup(brokerAddr, 10000L);
               Iterator var32 = allSubscriptionGroup.getSubscriptionGroupTable().values().iterator();

               while(var32.hasNext()) {
                  SubscriptionGroupConfig group = (SubscriptionGroupConfig)var32.next();
                  if (group.getGroupName().startsWith(mqProperties.getNamespace()) && !group_subscription.containsKey(group.getGroupName())) {
                     mqClient.getConsumeStats(brokerAddr, group.getGroupName(), 10000L).getOffsetTable().forEach((queue, offset) -> {
                        if (offset.getBrokerOffset() > offset.getConsumerOffset()) {
                           String var10002 = group.getGroupName();
                           throw new IllegalStateException("Subscription be canceled while unconsumed messages exist. " + var10002 + "-> [" + queue.getTopic() + "]");
                        }
                     });
                     mqClient.deleteSubscriptionGroup(brokerAddr, group.getGroupName(), true, 10000L);
                  }
               }
            }
         }

         Set<String> topicList = mqClient.getTopicListFromNameServer(10000L).getTopicList();
         MQAdminImpl mqAdmin = rocketMQTemplate.getProducer().getDefaultMQProducerImpl().getMqClientFactory().getMQAdminImpl();
         if (mqProperties.getRocketmq().isMqttEnabled() && !topicList.contains(mqttProperties.getEmqx().getParentTopic())) {
            mqAdmin.createTopic(mqProperties.getRocketmq().getTopicTemplate(), mqttProperties.getEmqx().getParentTopic(), mqttProperties.getEmqx().getParentTopicQueueNum());
         }

         var28 = mqProperties.getAllTopics().iterator();

         while(var28.hasNext()) {
            MQProperties.Topic topic = (MQProperties.Topic)var28.next();
            if (!topicList.contains(topic.getName())) {
               mqAdmin.createTopic(mqProperties.getRocketmq().getTopicTemplate(), topic.getName(), topic.getQueueNum());
            }
         }

         var28 = listenerContainers.iterator();

         while(var28.hasNext()) {
            listenerContainer = (RocketListenerContainer)var28.next();
            RocketListenerContainer finalListenerContainer = listenerContainer;
            genericApplicationContext.registerBean(listenerContainer.getName(), RocketListenerContainer.class, () -> {
               return finalListenerContainer;
            }, new BeanDefinitionCustomizer[0]);
         }

      } catch (Throwable var21) {
         throw var21;
      }
   }

   private RocketListenerContainer createMQListenerContainer(String name, Object bean, MQMessageListener annotation) {
      RocketListenerContainer container = new RocketListenerContainer();
      container.setNameServer(this.mqProperties.getRocketmq().getNameServer());
      container.setAccessKey(this.mqProperties.getRocketmq().getAccessKey());
      container.setSecretKey(this.mqProperties.getRocketmq().getSecretKey());
      container.setEnableMsgTrace(this.mqProperties.getRocketmq().getConsumer().isEnableMsgTrace());
      container.setCustomizedTraceTopic(this.mqProperties.getRocketmq().getConsumer().getCustomizedTraceTopic());
      container.setTlsEnable(this.mqProperties.getRocketmq().getConsumer().isTlsEnable());
      container.setMaxReconsumeTimes(annotation.maxReconsumeTimes());
      container.setTopic(this.environment.resolvePlaceholders(annotation.topic()));
      this.mqProperties.checkTopicDefinition(container.getTopic());
      container.setTag(this.environment.resolvePlaceholders(annotation.tag()));
      String var10001 = this.mqProperties.getNamespace();
      container.setConsumerGroup(var10001 + this.environment.resolvePlaceholders(annotation.group()));
      container.setMqListener((MQListener)bean);
      container.setMessageConverter(this.messageConverter);
      container.setName(name);
      return container;
   }
}
