package com.mortals.xhx.daemon.task;

import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.xhx.module.device.model.*;
import com.mortals.xhx.module.device.service.DeviceLogService;
import com.mortals.xhx.module.device.service.DeviceModuleService;
import com.mortals.xhx.module.device.service.DeviceModuleUseService;
import com.mortals.xhx.module.device.service.DeviceService;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

/**
 * 设备模块使用统计任务
 *
 * @author: zxfei
 * @date: 2022/3/9 15:19
 */
@CommonsLog
@Service("DeviceModuleUseTask")
public class DeviceModuleUseTaskImpl implements ITaskExcuteService {

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private DeviceLogService deviceLogService;
    @Autowired
    private DeviceModuleUseService deviceModuleUseService;
    @Autowired
    private DeviceModuleService moduleService;


    @Override
    public void excuteTask(ITask task) throws AppException {
        log.info("设备模块使用统计任务");
        doDeviceModuleUse();
    }


    /**
     * 统计设备模块使用率
     */
    private void doDeviceModuleUse() {
        Map<String, DeviceModuleEntity> moduleMap = moduleService.find(new DeviceModuleQuery()).stream().collect(Collectors.toMap(x -> x.getModuleMsgCode(), y -> y, (o, n) -> n));
        try {
            // TODO: 2022/7/2 根据每个设备单独查询统计 计算数据量会减少
            List<DeviceModuleUseEntity> moduleUseEntityList = deviceService.getCacheList().stream().flatMap(device -> {
                //查询当前设备日志
                List<DeviceLogEntity> deviceLogList = deviceLogService.find(new DeviceLogQuery().deviceId(device.getId()));
                //分组统计每个模块头使用率
                Map<String, Long> modelCollect = deviceLogList.parallelStream().collect(Collectors.groupingBy(DeviceLogEntity::getMessageHead, Collectors.counting()));
                return modelCollect.entrySet().stream().map(item -> {
                    if (moduleMap.containsKey(item.getKey())) {
                        DeviceModuleUseEntity deviceModuleUseEntity = new DeviceModuleUseEntity();
                        deviceModuleUseEntity.initAttrValue();
                        DeviceModuleEntity deviceModuleEntity = moduleMap.get(item.getKey());

                        deviceModuleUseEntity.setDeviceId(device.getId());
                        deviceModuleUseEntity.setModuleMsgCode(deviceModuleEntity.getModuleMsgCode());
                        deviceModuleUseEntity.setModuleName(deviceModuleEntity.getModuleName());
                        deviceModuleUseEntity.setUseNum(item.getValue());
                        deviceModuleUseEntity.setCreateUserId(1L);
                        deviceModuleUseEntity.setCreateTime(new Date());
                        return deviceModuleUseEntity;
                    }
                    return null;
                }).filter(f -> f != null);
            }).collect(Collectors.toList());

            if (!ObjectUtils.isEmpty(moduleUseEntityList)) {
                //遍历，更新统计数据表 标识 设备id与消息头
                Map<String, DeviceModuleUseEntity> collect = deviceModuleUseService.find(new DeviceModuleUseQuery()).stream().collect(Collectors.toMap(x -> x.getDeviceId() + "#" + x.getModuleMsgCode(), y -> y, (o, n) -> n));
                moduleUseEntityList.stream().forEach(mudule -> {
                    String key = mudule.getDeviceId() + "#" + mudule.getModuleMsgCode();
                    if (collect.containsKey(key)) {
                        //更新
                        DeviceModuleUseEntity deviceModuleUseEntity = collect.get(key);
                        mudule.setId(deviceModuleUseEntity.getId());
                        mudule.setUpdateTime(new Date());
                        mudule.setUpdateUserId(1L);
                        deviceModuleUseService.update(mudule, null);
                    } else {
                        //新增
                        deviceModuleUseService.save(mudule, null);
                    }
                });
            }
        } catch (Exception e) {
            log.error("更新任务异常，结束执行", e);
        }
    }

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

    }


}
