package com.bocloud.ims.service.topology;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.ims.entity.topology.InstanceMq;
import com.bocloud.ims.interfaces.topology.InstanceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * CMDB消息分发器
 *
 * @author dmw
 */
@Component("instanceMessageDispatcher")
public class InstanceMessageDispatcher implements CompletedNotify, InitializingBean {

    private static Logger logger = LoggerFactory.getLogger(InstanceMessageDispatcher.class);
    private BlockingQueue<String> messages = new LinkedBlockingQueue<>();
    private volatile boolean nextMessage = true;
    @Autowired
    private InstanceService instanceService;

    /**
     * 缓存消息
     *
     * @param message
     * @throws InterruptedException
     */
    public void cacheMessage(String message) throws InterruptedException {
        logger.info(message);
        messages.put(message);
        notice();
    }

    class Dispatcher implements Runnable {
        @Override
        public void run() {
            while (nextMessage) {
                nextMessage = false;
                String content = null;
                try {
                    logger.info("缓存队列中未处理的消息数量：" + messages.size());
                    content = messages.take();
                } catch (InterruptedException e) {
                    logger.error("Get instance message from queue InterruptedException!", e);
                    Thread.currentThread().interrupt();
                }
                if (StringUtils.hasText(content)) {
                    InstanceMq instanceMq = JSONObject.parseObject(content, InstanceMq.class);
                    instanceService.receive(instanceMq);
                    nextMessage = true;
                }
            }
        }

    }

    @Override
    public void notice() {
        this.nextMessage = true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        new Thread(new Dispatcher()).start();
    }
}
