package com.priusis;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.priusis.dto.HwPortControllerDto;
import com.priusis.utils.IHwPortController;
import com.priusis.vo.MqttRpcDataMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@EnableScheduling
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, SecurityAutoConfiguration.class})
public class ApqControlApplication {

    // 一分钟一次上报
    private final Long FIXED_DELAY = 60000L;

    @Autowired
    private RestTemplate restTemplate;

    public static void main(String[] args) {
        SpringApplication.run(ApqControlApplication.class, args);
    }

    @Scheduled(fixedDelay = 60000L)
    protected void controlProgramTask() {
        log.info("硬件监控上报=================");
        // 获取硬件监控配置 params == data
        ResponseEntity<MqttRpcDataMessage> forEntity = null;
        try {
            forEntity = restTemplate.getForEntity("http://localhost:8765/rpc_cmd/controll", MqttRpcDataMessage.class);
        } catch (Exception e) {
            log.error("硬件监控上报异常", e.getMessage());
        }
        if (null != forEntity) {
            MqttRpcDataMessage body = forEntity.getBody();
            String params = body.getParams();

            if (StrUtil.isNotBlank(params)) {
                Long sendTime = body.getSendTime();
                long current = System.currentTimeMillis();
                List<HwPortControllerDto> hwPortControllerDtos = JSONUtil.toList(params, HwPortControllerDto.class);
                // 初始化硬件接口管理模块
                int result = IHwPortController.instanceDll.APQ_HWPORT_Initialize();
                log.info("APQ_HWPORT_Initialize ret:{}", result);

                if (current - sendTime <= FIXED_DELAY && CollUtil.isNotEmpty(hwPortControllerDtos)) {
                    // 收到硬件策略下发请求
                    log.info("收到硬件策略下发请求, sendTime:{}, params:{}", sendTime, params);

                    for (HwPortControllerDto hwPortControllerDto : hwPortControllerDtos) {
                        HwPortControllerDto.DeviceHardwareEnum deviceHardwareEnum = hwPortControllerDto.getKey();
                        int doType = hwPortControllerDto.getDoType();
                        int limitType = hwPortControllerDto.getLimitType();
                        int value = hwPortControllerDto.getValue();

                        List<Integer> hwDeviceIds = deviceHardwareEnum.getHwDeviceIds();
                        String hwDeviceName = deviceHardwareEnum.getName();
                        // 设置普通设备权限
                        if (Objects.equals(deviceHardwareEnum.getHwGroup(), "Normal")) {
                            // 1F/2T
                            for (Integer hwDeviceId : hwDeviceIds) {
                                int perm = (doType == 1 ? 2 : 1);
                                int result32 = IHwPortController.instanceDll.APQ_HWPORT_set_normal_device_permit(hwDeviceId, perm, null);
                                log.info("APQ_HWPORT_set_normal_device_permit doType:{}, limitType;{}，value:{}, hwDeviceId:{}, name;{}, perm:{}, ret:{}",
                                        doType, limitType, value, hwDeviceId, hwDeviceName, perm, result32);
                            }
                        } else if (Objects.equals(deviceHardwareEnum.getHwGroup(), "Storage")) {  // 设置存储设备权限
                            // 1F/2T/3T-ALL/4T-R/5T-CI/6T-CO   拷出目前无用！！ Storage移动硬盘，TYPEC  无效  ！！
                            for (Integer hwDeviceId : hwDeviceIds) {
                                int perm = (doType == 1 ? 2 : 1);
                                if (perm == 2) {
                                    // limitType 1读写 2只读 3拷入 4拷出 5不限速 6限速
                                    perm = (limitType == 1 ? 3 : limitType == 2 ? 4 : limitType == 3 ? 5 : limitType == 4 ? 6 : 3);
                                }
                                int result32 = IHwPortController.instanceDll.APQ_HWPORT_set_storage_device_permit(hwDeviceId, perm, null);
                                log.info("APQ_HWPORT_set_storage_device_permit doType:{}, limitType;{}，value:{}, hwDeviceId:{}, name;{}, perm:{}, ret:{}",
                                        doType, limitType, value, hwDeviceId, hwDeviceName, perm, result32);
                            }
                        } else if (Objects.equals(deviceHardwareEnum.getHwGroup(), "NET")) {   // 设置网络设备权限
                            // 1F/2T/3T-NS/4T-S-200   网口，4G/5G模块，无线WIFI区分不了 ！！
                            for (Integer hwDeviceId : hwDeviceIds) {
                                int perm = (doType == 1 ? 2 : 1);
                                if (perm == 2) {
                                    // limitType 1读写 2只读 3拷入 4拷出 5不限速 6限速
                                    perm = (limitType == 5 ? 3 : limitType == 6 ? 4 : 2);
                                }
                                int result32 = IHwPortController.instanceDll.APQ_HWPORT_set_net_device_permit(hwDeviceId, perm, value, null);
                                log.info("APQ_HWPORT_set_net_device_permit doType:{}, limitType;{}，value:{}, hwDeviceId:{}, name;{}, perm:{}, ret:{}",
                                        doType, limitType, value, hwDeviceId, hwDeviceName, perm, result32);
                            }
                        }

                        // 应用硬件接口管理模块的配置内容
                        int result5 = IHwPortController.instanceDll.APQ_HWPORT_Apply();
                        log.info("APQ_HWPORT_Apply ret:{}", result5);
                    }

                } else {
                    log.info("执行硬件监控, sendTime:{}, params:{}", sendTime, params);

                    // 上报硬件监控数据
                    Map mapRequest = new HashMap();

                    for (HwPortControllerDto hwPortControllerDto : hwPortControllerDtos) {
                        HwPortControllerDto.DeviceHardwareEnum deviceHardwareEnum = hwPortControllerDto.getKey();
                        int doType = hwPortControllerDto.getDoType();
                        int limitType = hwPortControllerDto.getLimitType();
                        int value = hwPortControllerDto.getValue();

                        List<Integer> hwDeviceIds = deviceHardwareEnum.getHwDeviceIds();
                        String hwDeviceName = deviceHardwareEnum.getName();
                        // 设置普通设备权限
                        if (Objects.equals(deviceHardwareEnum.getHwGroup(), "Normal")) {
                            // 1F/2T
                            for (Integer hwDeviceId : hwDeviceIds) {
                                int perm = (doType == 1 ? 2 : 1);
                                if (perm == 1) {
                                    // 获取普通设备权限
                                    int result31 = IHwPortController.instanceDll.APQ_HWPORT_get_normal_device_permit(hwDeviceId);
                                    log.debug("APQ_HWPORT_get_normal_device_permit doType:{}, limitType;{}，value:{}, hwDeviceId:{}, name;{}, perm:{}, ret:{}",
                                            doType, limitType, value, hwDeviceId, hwDeviceName, perm, result31);
                                    if (result31 == 2) {
                                        mapRequest.put(deviceHardwareEnum.name(), perm);
                                    }
                                }
                            }
                        } else if (Objects.equals(deviceHardwareEnum.getHwGroup(), "Storage")) {  // 设置存储设备权限
                            // 1F/2T/3T-ALL/4T-R/5T-CI/6T-CO   拷出目前无用！！ Storage移动硬盘，TYPEC  无效  ！！
                            for (Integer hwDeviceId : hwDeviceIds) {
                                int perm = (doType == 1 ? 2 : 1);
                                if (perm == 2) {
                                    // limitType 1读写 2只读 3拷入 4拷出 5不限速 6限速
                                    perm = (limitType == 1 ? 3 : limitType == 2 ? 4 : limitType == 3 ? 5 : limitType == 4 ? 6 : 3);
                                }

                                int result32 = IHwPortController.instanceDll.APQ_HWPORT_get_storage_device_permit(hwDeviceId);
                                log.info("APQ_HWPORT_get_storage_device_permit doType:{}, limitType;{}，value:{}, hwDeviceId:{}, name;{}, perm:{}, ret:{}",
                                        doType, limitType, value, hwDeviceId, hwDeviceName, perm, result32);
                                if (perm != result32) {
                                    mapRequest.put(deviceHardwareEnum.name(), perm);
                                }
                            }
                        } else if (Objects.equals(deviceHardwareEnum.getHwGroup(), "NET")) {   // 设置网络设备权限
                            // 1F/2T/3T-NS/4T-S-200   网口，4G/5G模块，无线WIFI区分不了 ！！
                            for (Integer hwDeviceId : hwDeviceIds) {
                                int perm = (doType == 1 ? 2 : 1);
                                if (perm == 2) {
                                    // limitType 1读写 2只读 3拷入 4拷出 5不限速 6限速
                                    perm = (limitType == 5 ? 3 : limitType == 6 ? 4 : 2);
                                }
                                int result32 = IHwPortController.instanceDll.APQ_HWPORT_get_net_device_permit(hwDeviceId, 0);
                                log.info("APQ_HWPORT_get_net_device_permit doType:{}, limitType;{}，value:{}, hwDeviceId:{}, name;{}, perm:{}, ret:{}",
                                        doType, limitType, value, hwDeviceId, hwDeviceName, perm, result32);
                                if (perm != result32) {
                                    mapRequest.put(deviceHardwareEnum.name(), perm);
                                }
                            }
                        }
                    }

                    if (mapRequest.size() > 0) {
                        Map eventMapRequest = new HashMap();
                        eventMapRequest.put("methodName", "control_warning");
                        eventMapRequest.put("params", mapRequest);
                        Map map = restTemplate.postForObject("http://localhost:8765/uplink_event/oc-client", eventMapRequest, Map.class);
                        log.info("存在硬件接口扫码告警，上报告警事件: mapData:{}, ret:{}", mapRequest, map);
                    }
                }

                // 清理硬件接口管理模块
                int result2 = IHwPortController.instanceDll.APQ_HWPORT_Uninitialize();
                log.info("APQ_HWPORT_Uninitialize ret:{}", result2);
            } else {
                log.info("未获取到获取硬件监控配置");
            }
        } else {
            log.info("未获取到获取硬件监控配置");
        }
    }
}
