package com.mortals.xhx.daemon.task;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.BizLogPdu;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.IMessageProduceService;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.xhx.common.code.DeviceMethodEnum;
import com.mortals.xhx.common.code.DeviceStatusEnum;
import com.mortals.xhx.common.code.LogTypeEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceQuery;
import com.mortals.xhx.module.device.service.DeviceService;
import com.mortals.xhx.module.platform.model.PlatformEntity;
import com.mortals.xhx.module.platform.service.PlatformService;
import com.mortals.xhx.module.product.model.ProductEntity;
import com.mortals.xhx.module.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 设备状态修正
 */
@Slf4j
@Service("DeviceStatTask")
public class DeviceStatTaskImpl implements ITaskExcuteService {
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private ProductService productService;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private IMessageProduceService messageProducer;

    @Override
    public void excuteTask(ITask task) throws AppException {
        log.info("设备状态修正任务");
        List<DeviceEntity> waitDeviceInfos = new ArrayList<>();
        while (true) {
            DeviceEntity deviceEntity = cacheService.lpop(RedisKey.KEY_DEVICE_ONLINE_QUEUE, DeviceEntity.class);
            if (ObjectUtils.isEmpty(deviceEntity)) {
                log.info("deviceEntity:{}",deviceEntity==null);
                break;
            } else {
                waitDeviceInfos.add(deviceEntity);
            }
            try {
                Thread.sleep(0);
            } catch (InterruptedException e) {
              log.error("线程休眠异常！",e);
            }
        }

        log.info("waitDeviceInfos size:{}", waitDeviceInfos.size());
        if (!ObjectUtils.isEmpty(waitDeviceInfos)) {
            deviceService.update(waitDeviceInfos);
        }
        //获取所有在线设备
        List<DeviceEntity> deviceList = deviceService.find(new DeviceQuery().deviceStatus(DeviceStatusEnum.在线.getValue()));
        //更新离线
        List<DeviceEntity> deviceOfflineList = deviceList.parallelStream().map(item -> {
            if (ObjectUtils.isEmpty(item.getDeviceCode())) return null;
            boolean exists = cacheService.exists(RedisKey.KEY_DEVICE_ONLINE_CACHE + item.getDeviceCode());
            if (!exists) {
                item.setDeviceStatus(DeviceStatusEnum.离线.getValue());
                item.setOfflineTime(new Date());
                return item;
            }
            return null;
        }).filter(f -> f != null).collect(Collectors.toList());

        if (!ObjectUtils.isEmpty(deviceOfflineList)) {
            log.info("修正设备数量:size:{}", deviceOfflineList.size());
            deviceService.update(deviceOfflineList);
            deviceOfflineList.forEach(deviceEntity -> {
                PlatformEntity platformEntity = platformService.getCache(deviceEntity.getPlatformId().toString());
                ProductEntity productEntity = productService.getCache(deviceEntity.getProductId().toString());
                if (!ObjectUtils.isEmpty(platformEntity) && !ObjectUtils.isEmpty(productEntity)) {
                    //通知第三方平台
                    deviceService.sendThirdParty(deviceEntity, productEntity, platformEntity, DeviceMethodEnum.OFFLINE);

                 //保存业务消息为离线
                    BizLogPdu bizLogPdu = new BizLogPdu();
                    bizLogPdu.initAttrValue();
                    //保存为产品名称
                    bizLogPdu.setAppName(productEntity.getProductCode());
                    bizLogPdu.setTraceID(IdUtil.objectId());
                    bizLogPdu.setUserCode("system");
                    bizLogPdu.setDeviceCode(deviceEntity.getDeviceCode());
                    bizLogPdu.setEventTopic("offline");
                    bizLogPdu.setEventTopicName(LogTypeEnum.上报事件.name());
                    bizLogPdu.setMsg(Base64.encode("设备离线"));
                    bizLogPdu.setLogLevel("INFO");
                    bizLogPdu.setLogTime(new Date());
                    messageProducer.syncBizSend(bizLogPdu);

                }
            });
        }
    }


    @Override
    public void stopTask(ITask task) throws AppException {

    }


}
