package com.mortals.xhx.daemon.applicationservice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.springcloud.service.IApplicationStartedService;
import com.mortals.xhx.base.framework.ws.message.SendToAllRequest;
import com.mortals.xhx.base.framework.ws.util.WebSocketUtil;
import com.mortals.xhx.busiz.req.DeviceReq;
import com.mortals.xhx.common.code.ActiveEnum;
import com.mortals.xhx.common.code.DeviceOnlineStatusEnum;
import com.mortals.xhx.common.code.StatusEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceLogEntity;
import com.mortals.xhx.module.device.model.DeviceQuery;
import com.mortals.xhx.module.device.service.DeviceLogService;
import com.mortals.xhx.module.device.service.DeviceService;
import com.mortals.xhx.queue.DefaultTbCoreConsumerService;
import com.mortals.xhx.queue.TbQueueConsumer;
import com.mortals.xhx.queue.TbQueueMsg;
import com.mortals.xhx.queue.TopicPartitionInfo;
import com.mortals.xhx.utils.IotThreadFactory;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;


@Component
@CommonsLog
public class DeviceMsgComsumerStartedService implements IApplicationStartedService {

    @Autowired
    private DefaultTbCoreConsumerService consumerService;
    @Autowired
    private DeviceLogService deviceLogService;
    @Autowired
    private DeviceService deviceService;

    protected volatile ExecutorService consumersExecutor;


    protected Boolean stopped = false;

    @Override
    public void start() {
        log.info("开始服务..[配置已加载完成，并且所有框架都已经初始化]");
        TbQueueConsumer<TbQueueMsg> mainConsumer = consumerService.getMainConsumer();
        if (!ObjectUtils.isEmpty(mainConsumer)) {
            //订阅所有已几快活设备
            Set<TopicPartitionInfo> topicPartitionInfoSet = deviceService.find(new DeviceQuery().active(ActiveEnum.已激活.getValue()).status(StatusEnum.启用.getValue())).stream()
                    .map(item ->
                            new TopicPartitionInfo(Constant.UPLOAD_TOPIC + item.getDeviceMac(), null)
                    ).collect(Collectors.toSet());
            mainConsumer.subscribe(topicPartitionInfoSet);
            log.info("消费线程订阅设备上报消息成功！：" + JSON.toJSONString(topicPartitionInfoSet));
            this.consumersExecutor = Executors.newCachedThreadPool(IotThreadFactory.forName("消费queue线程"));

            consumersExecutor.submit(() -> {
                while (!stopped) {
                    try {

                        TbQueueMsg queueMsg = consumerService.getComsureQueue().poll();
                        if (!ObjectUtils.isEmpty(queueMsg)) {
                            //做相应业务,做日志操作
                            DeviceReq deviceReq = JSON.parseObject(new String(queueMsg.getData()), DeviceReq.class);
                            boolean bool = false;
                            DeviceEntity deviceEntity = deviceService.getExtCache(deviceReq.getDeviceNum());
                            if (!ObjectUtils.isEmpty(deviceEntity)) {

                                if (deviceEntity.getDeviceOnlineStatus() == DeviceOnlineStatusEnum.离线.getValue()) {
                                    bool = true;
                                }
                                deviceEntity.setOnlineTime(new Date());
                                deviceEntity.setDeviceOnlineStatus(DeviceOnlineStatusEnum.在线.getValue());
                                deviceEntity.setIp(deviceReq.getIp());
                                deviceEntity.setPort(deviceReq.getPort());
                               // deviceEntity.setSiteNum(deviceReq.getSitenum());
                                deviceEntity.setCenternum(deviceReq.getCenternum());
                                deviceService.update(deviceEntity);

                                DeviceLogEntity deviceLogEntity = new DeviceLogEntity();
                                deviceLogEntity.initAttrValue();
                                deviceLogEntity.setDeviceId(deviceEntity.getId());
                                deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
                                deviceLogEntity.setDeviceNum(deviceEntity.getDeviceCode());
                                deviceLogEntity.setContent(JSONObject.toJSONString(deviceReq));
                                deviceLogEntity.setCreateTime(new Date());
                                deviceLogService.save(deviceLogEntity);

                                if (bool) {
                                    WebSocketUtil.broadcast(SendToAllRequest.TYPE, new SendToAllRequest().setContent(JSON.toJSONString(deviceEntity)));
                                }
                            }

                        }

                    } catch (Exception e) {
                        if (!stopped) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e2) {
                            }
                        }
                    }
                }

                mainConsumer.commit();
            });


        }
    }

    @Override
    public void stop() {
        log.info("停止服务..");
//        if (mainConsumer != null) {
//            mainConsumer.unsubscribe();
//        }
    }

    @Override
    public int getOrder() {
        return 10;
    }

}
