package com.dcs.equipment.service.impl;

import com.dcs.equipment.domain.DeviceRequest;
import com.dcs.equipment.domain.DeviceResponse;
import com.dcs.equipment.task.ModbusTcpTask;
import com.dcs.equipment.utils.ModbusUtil;
import com.dcs.hnyz.domain.EquipmentParam;
import com.dcs.hnyz.service.IEquipmentParamService;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import com.dcs.equipment.service.DeviceService;

import java.util.*;
import java.util.concurrent.CompletableFuture;

import static com.dcs.equipment.constants.ModbusConstants.*;

/**
 * @author: LaFantasque
 * @date: 2025-06-30 22:05
 */
@Service
public class DeviceServiceImpl implements DeviceService {

    private static final Logger logger = LoggerFactory.getLogger("DeviceService");
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private IEquipmentParamService equipmentParamService;

    // 更新设备寄存器信息和数据地址
    public void updateEquipmentCodes() {
        EquipmentParam dcsEquipment = new EquipmentParam();
        List<EquipmentParam> newEquipmentParamList = equipmentParamService.selectEquipmentParamList(dcsEquipment);
        ModbusTcpTask.deviceRequestList = Collections.unmodifiableList(ModbusUtil.getDeviceRequests(newEquipmentParamList));
        // 按照顺序存储数据
        newEquipmentParamList.sort(Comparator.comparing(EquipmentParam::getRegisterId));
        ModbusTcpTask.equipmentParamList = Collections.unmodifiableList(newEquipmentParamList);
    }

    @Override
    public List<Object> getValues(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
        return ModbusUtil.getValues(request);
    }
    @Override
    public Map<String, List<DeviceResponse>> getResponseMapByDeviceRequests(List<DeviceRequest> requests) {
        // modbus请求次数
        int requestNum = requests.size();
        // 保存modbus响应信息
        Map<String, List<DeviceResponse>> deviceResponseMap = new HashMap<>();
        deviceResponseMap.put(COIL_FUNCTION_CODE, new ArrayList<>());
        deviceResponseMap.put(INPUT_FUNCTION_CODE, new ArrayList<>());
        deviceResponseMap.put(HOLDING_FUNCTION_CODE, new ArrayList<>());
        CompletableFuture<Void>[] futures = new CompletableFuture[requestNum];
        for (int i = 0; i < requestNum; i++) {
            int finalI = i;
            try {
                futures[finalI] = CompletableFuture.runAsync(() -> {
                    DeviceRequest deviceRequest = requests.get(finalI);
                    List<Object> list = new ArrayList<>();
                    // 响应数据
                    DeviceResponse response = new DeviceResponse();
                    response.setUnitId(deviceRequest.getUnitId());
                    response.setResource(deviceRequest.getResource());
                    response.setDataType(deviceRequest.getDataType());
                    response.setOffsetOrIndex(deviceRequest.getOffsetOrIndex());
                    response.setLengthOrQos(deviceRequest.getLengthOrQos());
                    try {
                        list = getValues(deviceRequest);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    response.setData(list);
                    deviceResponseMap.get(deviceRequest.getResource()).add(response);
                }, threadPoolTaskExecutor);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            CompletableFuture.allOf(futures).get();  // 等待所有任务完成
        } catch (Exception e) {
            e.printStackTrace();
        }
        return deviceResponseMap;
    }

}