package com.yeejoin.amos.iec104.tcp;

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

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.yeejoin.amos.iec104.business.param.PacketParam;
import com.yeejoin.amos.iec104.tcp.client.invoke.RecDataQueue;
import com.yeejoin.amos.iec104.tcp.entity.Apdu;
import com.yeejoin.amos.iec104.tcp.utils.ChangeUtils;
import com.yeejoin.amos.iec104.websocket.EquipmentWebsocket;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class WebSocketQueue {
	private static final BlockingQueue<PacketParam> blockingQueue = new LinkedBlockingQueue<PacketParam>();
	private volatile static WebSocketQueue instance = null;
	ScheduledExecutorService service = null;
	
	private WebSocketQueue() {
	}
	
    public static WebSocketQueue getInstance(){
    	//先检查实例是否存在，如果不存在才进入下面的同步块
         if(instance == null){
        	 //同步块，线程安全的创建实例
             synchronized(RecDataQueue.class){
            	 //再次检查实例是否存在，如果不存在才真的创建实例
                 if(instance == null){
                     instance = new WebSocketQueue();
                 }
             }
         }
         return instance;
    }
	
    /**
     * 启动apdu数据消费任务
     */
    public void start() {
    	service = Executors.newSingleThreadScheduledExecutor();
        // 第二个参数为首次执行的延时时间，第三个参数为定时执行的间隔时间
    	service.execute(task_runnable);
    }
    
	public void add(PacketParam packet) {
		blockingQueue.add(packet);
	}
	
	Runnable task_runnable = new Runnable() {
        public void run() {
            while(true) {
            	try {
            		PacketParam data = blockingQueue.take();
            		byte[] conent = ChangeUtils.hexStringToBytes(data.getConent());
            		ByteBuf buf = Unpooled.buffer(conent.length);
            		buf.markReaderIndex();
            		buf.writeBytes(conent);
            		buf.resetReaderIndex();
//            		Logger.getLogger(this.getClass()).error("conent length is " + buf.readableBytes());
//            		Logger.getLogger(this.getClass()).error("buf can read length is " + buf.readableBytes());
            		if (buf.readableBytes() == conent.length) {
                		Apdu apdu = new Apdu(buf);
                		data.setPackateType(apdu.getApciType().name());
    					EquipmentWebsocket.sendInfo(JSON.toJSONString(data));
            		}
					buf.clear();
					buf = null;
				} catch (Exception  e) {
					Logger.getLogger(this.getClass()).error(e.getMessage());
					e.printStackTrace();
				} 
            }
        }
    };
}
