package com.sptg.device.biz.receiver;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.sptg.common.core.enums.Instruct;
import com.sptg.common.core.util.VersionUtil;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.stream.DeviceUpdateReceiverInterface;
import com.sptg.device.biz.service.DeviceServiceInterface;
import com.sptg.device.biz.service.MsgPublishService;
import com.sptg.permissions.api.entity.AppPackage;
import com.sptg.permissions.api.feigns.AppPackageFeign;
import com.sptg.permissions.api.feigns.ConfFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * title: DeviceUpdateReceiver
 * description: 设备更新消费者
 *
 *
 *
 */
@Component
@Slf4j
@RequiredArgsConstructor
@EnableBinding(value = { DeviceUpdateReceiverInterface.class})
public class DeviceUpdateReceiver {

    @StreamListener(value = DeviceUpdateReceiverInterface.INPUT)
    public void input(AppPackage appPackage){
        //  判断更新方式
        switch (appPackage.getUpdateMethod()){
            //  指定安装包，更新所有相匹配的设备
            case 1:
                if (StringUtils.isEmpty(appPackage.getDeviceFactory()) ||
                        appPackage.getDeviceModelNumber().isEmpty() ||
                        null == appPackage.getVersion()){
                    log.error("设备厂商,设备型号,安装包版本号不能为空");
                    return;
                }
                this.updateByPackage(appPackage);
                break;
            //  指定设备更新到最新版本
            case 2:
                if (null == appPackage.getDeviceIds() || appPackage.getDeviceIds().length == 0){
                    log.error("设备厂商,设备型号,安装包版本号不能为空");
                    return;
                }
                this.updateByDeviceIds(Arrays.asList(appPackage.getDeviceIds()));
                break;
            //  指定设备更新到指定版本【设备列表选择版本升级】
            case 3:
                if (null == appPackage.getDeviceIds() || appPackage.getDeviceIds().length == 0 || appPackage.getId() == null){
                    log.error("设备厂商,设备型号,安装包ID不能为空");
                    return;
                }
                this.updateByDeviceIdsAndPkg(appPackage.getId(), Arrays.asList(appPackage.getDeviceIds()));
                break;
            //  指定恢复包，更新所有相匹配的设备
            case 4:
                if (StringUtils.isEmpty(appPackage.getDeviceFactory()) ||
                        appPackage.getDeviceModelNumber().isEmpty() ||
                        null == appPackage.getVersion()){
                    log.error("设备厂商,设备型号,恢复包版本号不能为空");
                    return;
                }
                this.updateRestoreByPackage(appPackage);
                break;
            default:break;
        }
    }

    private final ConfFeign confFeign;

    private void updateByPackage(AppPackage appPackage){
        //  获取设备列表
        Wrapper<Device> wrapper = new EntityWrapper<>();
        wrapper.eq("s_device_factory",appPackage.getDeviceFactory());
        wrapper.eq("s_type_code",appPackage.getDeviceModelNumber());
//        wrapper.lt("i_version_number",appPackage.getVersion());
        List<Device> deviceList = this.deviceServiceInterface.selectList(wrapper);
        if (deviceList.size() > 0){
            String host = this.confFeign.getFileServerHost();
            appPackage.setDownloadUrl(host + appPackage.getDownloadUrl());
            Map<String,String> map = new HashMap<>();
            //版本号
            if (!StringUtils.isEmpty(appPackage.getVersion())){
                map.put("version",appPackage.getVersion());
            }else {
                map.put("version",null);
            }
            //  下发更新指令
            this.msgPublishService.batchPushInstruct(appPackage,deviceList, Instruct.update_app_package,map);
        }
    }

    private void updateRestoreByPackage(AppPackage appPackage){
        //  获取设备列表
        Wrapper<Device> wrapper = new EntityWrapper<>();
        wrapper.eq("s_device_factory",appPackage.getDeviceFactory());
        wrapper.eq("s_type_code",appPackage.getDeviceModelNumber());
//        wrapper.lt("i_version_number",appPackage.getVersion());
        List<Device> deviceList = this.deviceServiceInterface.selectList(wrapper);
        if (deviceList.size() > 0){
            String host = this.confFeign.getFileServerHost();
            appPackage.setDownloadUrl(host + appPackage.getDownloadUrl());
            Map<String,String> map = new HashMap<>();
            //版本号
            if (!StringUtils.isEmpty(appPackage.getVersion())){
                map.put("version",appPackage.getVersion());
            }else {
                map.put("version",null);
            }
            //  下发更新指令
            this.msgPublishService.batchPushInstruct(appPackage,deviceList, Instruct.update_restore_app_package, map);
        }
    }

    private final DeviceServiceInterface deviceServiceInterface;
    private final AppPackageFeign appPackageFeign;
    private final MsgPublishService msgPublishService;

    private void updateByDeviceIds(List<Long> deviceIdList){
        //  获取设备列表
        Wrapper<Device> wrapper = new EntityWrapper<>();
        wrapper.in("l_id", deviceIdList);
        wrapper.isNotNull("s_device_factory");
        wrapper.isNotNull("s_type_code");
        List<Device> deviceList = this.deviceServiceInterface.selectList(wrapper);
        if (deviceList.size() == 0){
            return;
        }
        String host = this.confFeign.getFileServerHost();
        //  根据设备厂商分组
        Map<String, List<Device>> factoryMap = deviceList.stream()
                .collect(Collectors.groupingBy(Device::getDeviceFactory));
        factoryMap.keySet().forEach(factoryName -> {
            //  根据设备型号分组
            Map<String, List<Device>> modelMap = factoryMap.get(factoryName)
                    .stream()
                    .collect(Collectors.groupingBy(Device::getDeviceModelNumber));
            modelMap.keySet().forEach(modelName -> {
                AppPackage dto = new AppPackage();
                dto.setDeviceFactory(factoryName);
                dto.setDeviceModelNumber(modelName);
                //  获取该型号的最新安装包版本
                AppPackage appPackage = this.appPackageFeign.getNewestVersion(dto);
                if (null != appPackage){
                    //  过滤版本号大于或等于当前包的版本的设备
                    List<Device> list = modelMap.get(modelName).stream()
                            .filter(device -> VersionUtil.compareTo(device.getVersionNumber(),appPackage.getVersion()))
                            .collect(Collectors.toList());
                    if (list.size() > 0) {
                        appPackage.setDownloadUrl(host + appPackage.getDownloadUrl());
                        Map<String,String> map = new HashMap<>();
                        //版本号
                        if (!StringUtils.isEmpty(appPackage.getVersion())){
                            map.put("version",appPackage.getVersion());
                        }else {
                            map.put("version",null);
                        }
                        //  下发更新指令
                        this.msgPublishService.batchPushInstruct(appPackage,list, Instruct.update_app_package,map);
                    }
                }else {
                    log.error("请先上传设备安装包");
                }
            });
        });


    }

    /**
     * 指定设备更新到指定升级包
     * @param pkgId
     * @param deviceIdList
     */
    private void updateByDeviceIdsAndPkg(Long pkgId, List<Long> deviceIdList){
        //  获取设备列表
        Wrapper<Device> wrapper = new EntityWrapper<>();
        wrapper.in("l_id", deviceIdList);
        wrapper.isNotNull("s_device_factory");
        wrapper.isNotNull("s_type_code");
        List<Device> deviceList = this.deviceServiceInterface.selectList(wrapper);
        if (deviceList.size() == 0){
            return;
        }
        String host = this.confFeign.getFileServerHost();
        AppPackage appPackage = this.appPackageFeign.getEntity(pkgId);
        if (null != appPackage){
            appPackage.setDownloadUrl(host + appPackage.getDownloadUrl());
            Map<String,String> map = new HashMap<>();
            //版本号
            if (!StringUtils.isEmpty(appPackage.getVersion())){
                map.put("version",appPackage.getVersion());
            }else {
                map.put("version",null);
            }
            //  下发更新指令
            this.msgPublishService.batchPushInstruct(appPackage,deviceList, Instruct.update_app_package,map);
        }else {
            log.error("请先上传设备安装包");
        }
    }

}
