
package com.mortals.xhx.queue;

import com.mortals.xhx.queue.processing.AbstractConsumerService;
import com.mortals.xhx.queue.provider.TbCoreQueueFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;

@Service
@Slf4j
public class DefaultTbCoreConsumerService extends AbstractConsumerService<TbQueueMsg> implements TbCoreConsumerService {

    @Value("${queue.core.poll-interval}")
    private long pollDuration;
    @Value("${queue.core.pack-processing-timeout}")
    private long packProcessingTimeout;

    private  TbQueueConsumer<TbQueueMsg> mainConsumer;

    public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory) {
        this.mainConsumer = tbCoreQueueFactory.createMsgConsumer();
    }

    @PostConstruct
    public void init() {
        log.info("初始化消费服务线程");
        super.init("core-consumer");
        // super.init("tb-core-consumer", "tb-core-notifications-consumer");
    }

    @PreDestroy
    public void destroy() {
        super.destroy();
    }

    @EventListener(ApplicationReadyEvent.class)
    @Order(value = 2)
    public void onApplicationEvent(ApplicationReadyEvent event) {
        super.onApplicationEvent(event);
    }


    @Override
    protected void launchMainConsumers() {
        log.info("启动消费线程！");
        consumersExecutor.submit(() -> {
            while (!stopped) {
                try {
                    List<TbQueueMsg> msgs = mainConsumer.poll(pollDuration);
                    if (msgs.isEmpty()) {
                        continue;
                    }
                    for (TbQueueMsg item:msgs){
                        log.info("msg:"+item.toString());
                    }

                    mainConsumer.commit();
                } catch (Exception e) {
                    if (!stopped) {
                        log.warn("Failed to obtain messages from queue.", e);
                        try {
                            Thread.sleep(pollDuration);
                        } catch (InterruptedException e2) {
                            log.trace("Failed to wait until the server has capacity to handle new requests", e2);
                        }
                    }
                }
            }
            log.info(" Core Consumer stopped.");
        });
    }

    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {

    }

    private static class PendingMsgHolder {
//        @Getter
//        @Setter
//        private volatile ToCoreMsg toCoreMsg;
    }


    @Override
    protected void stopMainConsumers() {
        if (mainConsumer != null) {
            mainConsumer.unsubscribe();
        }

    }

}
