package com.community.huiju.runner;

import com.community.huiju.common.hk.code.EventDis;
import com.community.huiju.service.MqMessageServiceI;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.Topic;

/**
 * @author FXF
 * @date 2018-11-23
 */
@Component
public class MqRunner implements ApplicationRunner {
	
	@Value("${broker.url}")
	private String BROKER_URL;
	
	public static final String TARGET = "openapi.acs.topic";
	
	@Autowired
	private MqMessageServiceI mqMessageService;
	
	@Override
	public void run(ApplicationArguments args) throws Exception {
		
		Connection connection = null;
		Session session = null;
		try {
			// 创建链接工厂
			ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(BROKER_URL);
			// 通过工厂创建一个连接
			connection = factory.createConnection();
			// factory.createConnection(userName, password)
			// 启动连接
			connection.start();
			// 第一个参数表示是否使用事务，第二个参数指定消息的确认模式
			session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			Topic topic = session.createTopic(TARGET);
			MessageConsumer consumer = session.createConsumer(topic);
			// 消费者异步接收topic里的消息
			consumer.setMessageListener(new MessageListener() {
				@Override
				public void onMessage(Message msg) {
					try {
						// cms里发送的消息为BytesMessage，此处不做判断亦可
						if (msg instanceof BytesMessage) {
							BytesMessage bytesMessage = (BytesMessage)msg;
							long length = bytesMessage.getBodyLength();
							byte[] bt = new byte[(int)length];
							// 将BytesMessage转换为byte类型
							bytesMessage.readBytes(bt);
							// 壳文件字段，EventDis类为event_dis.proto文件解析而来，CommEventLog类为事件壳文件类
							EventDis.CommEventLog parseFrom = EventDis.CommEventLog.parseFrom(bt);
							
							//插入数据库
							mqMessageService.saveMqMessage(parseFrom);
							// 输出壳文件字段
							//System.out.println(parseFrom.toString());
							// 扩展字段，此字段为设备上报事件内容，部分事件需要使用pb文件再次解析
							//ByteString extInfo = parseFrom.getExtInfo();
							// 输出扩展字段
							//System.out.println("序列化解析：" + AcsEvent.AccessEventLog.parseFrom(extInfo));
						}
					} catch (Exception e) {
						System.out.println("订阅程序出错！");
						e.printStackTrace();
					}
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
