package org.nl.acs.route.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.AllArgsConstructor;
import org.nl.acs.auto.initial.ApplicationAutoInitial;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.enums.DeviceType;
import org.nl.acs.device.service.mapper.DeviceMapper;
import org.nl.acs.device_driver.RouteableDeviceDriver;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.route.service.RoutePlanService;
import org.nl.acs.route.service.dto.RoutePlanDto;
import org.nl.acs.common.base.PageInfo;
import org.nl.acs.common.base.QueryHelpMybatisPlus;
import org.nl.acs.common.base.impl.CommonServiceImpl;
import org.nl.common.exception.BadRequestException;
import org.nl.acs.utils.ConvertUtil;
import org.nl.common.utils.FileUtil;
import org.nl.acs.utils.PageUtil;
import org.nl.acs.route.domain.RouteLine;
import org.nl.acs.route.service.RouteLineService;
import org.nl.acs.route.service.dto.RouteLineDto;
import org.nl.acs.route.service.dto.RouteLineQueryParam;
import org.nl.acs.route.service.mapper.RouteLineMapper;
import org.nl.common.utils.SecurityUtils;
import org.nl.system.service.param.ISysParamService;
import org.nl.system.service.param.dao.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author jiaolm
* @date 2023-05-09
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = RouteLineService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class RouteLineServiceImpl extends CommonServiceImpl<RouteLineMapper, RouteLine> implements RouteLineService, ApplicationAutoInitial {

    @Autowired
    ISysParamService paramService;

    Map<String, RoutePlanDto> routePlans = new HashMap();
    Map<Integer, String> routeIndex = new HashMap();
    Map<String, List> routeLines = new HashMap();

    Map<String, Integer> deviceCoordinate = null;//用来确定设备在 路由二维数组中的坐标
    Map<String, String> routeChart[][] = null;//路由二维数组
    List<Map> routePlansList = new ArrayList<>();
    // private final RedisUtils redisUtils;
    private final RouteLineMapper routeLineMapper;
    private final DeviceMapper deviceMapper;
    @Autowired
    private RoutePlanService routePlanService;
    @Autowired
    private DeviceAppService deviceAppService;

    @Override
    public PageInfo<RouteLineDto> queryAll(RouteLineQueryParam query, Pageable pageable) {
        IPage<RouteLine> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<RouteLine> page = routeLineMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, RouteLineDto.class);
    }

    @Override
    public List<RouteLineDto> queryAll(RouteLineQueryParam query){
        return ConvertUtil.convertList(routeLineMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), RouteLineDto.class);
    }

    @Override
    public RouteLine getById(String id) {
        return routeLineMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public RouteLineDto findById(String id) {
        return ConvertUtil.convert(getById(id), RouteLineDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(RouteLineDto resources) {
        RouteLine entity = ConvertUtil.convert(resources, RouteLine.class);
        return routeLineMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(RouteLineDto resources){
        RouteLine entity = ConvertUtil.convert(resources, RouteLine.class);
        int ret = routeLineMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids){
        // delCaches(ids);
        return routeLineMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(String id){
        Set<String> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }


    @Override
    public Map<String, Object> queryAll(Map whereJson, Pageable page) {
        String device_code = (String) whereJson.get("device_code");
        String next_device_code = (String) whereJson.get("next_device_code");
        String route_plan_id = (String) whereJson.get("route_plan_id");
        IPage<RouteLine> queryPage = PageUtil.toMybatisPage(page);
        QueryWrapper<RouteLine> wrapper = new QueryWrapper<>();
        wrapper.eq("line.is_delete","0");
        wrapper.like(StringUtils.isNotBlank(device_code), "line.device_code",device_code);
        wrapper.like(StringUtils.isNotBlank(next_device_code), "line.next_device_code",next_device_code);
        wrapper.eq(StringUtils.isNotBlank(route_plan_id), "line.route_plan_id",route_plan_id);
        wrapper.orderByDesc("line.create_time");
        IPage<RouteLine> routeLinePage = routeLineMapper.queryPage(queryPage,wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(routeLinePage, RouteLine.class));
        return json;
    }

    @Override
    public List<RouteLineDto> queryAll(Map whereJson) {
        List<RouteLine>  list= new LambdaQueryChainWrapper<>(routeLineMapper)
                .list();
        return ConvertUtil.convertList(list, RouteLineDto.class);
    }

//    @Override
//    public RouteLineDto findById(String line_uuid) {
//        WQLObject wo = WQLObject.getWQLObject("acs_route_line");
//        JSONObject json = wo.query("line_uuid ='" + line_uuid + "'").uniqueResult(0);
//        final RouteLineDto obj = json.toJavaObject(RouteLineDto.class);
//        return obj;
//    }

    @Override
    public RouteLineDto findByCode(String code) {
        RouteLine routeLine= new LambdaQueryChainWrapper<>(routeLineMapper)
                .eq(RouteLine::getDevice_code, code)
                .one();
        if(ObjectUtil.isEmpty(routeLine)){
            return null;
        }
        return ConvertUtil.convert(routeLine, RouteLineDto.class);
    }

//    @Override
//    public JSONArray queryAll(String code, String plan_uuid) {
//        JSONArray arr = WQLObject.getWQLObject("acs_route_line").query(" is_active= '1' and  device_code = '" + code + "' and route_plan_id='" + plan_uuid + "'").getResultJSONArray(0);
//        return arr;
//    }

//    @Override
//    public JSONArray querySuperiorLine(String code, String plan_uuid) {
//        JSONArray arr = WQLObject.getWQLObject("acs_route_line").query(" is_active= '1' and  next_device_code = '" + code + "'and route_plan_id='" + plan_uuid + "'").getResultJSONArray(0);
//        return arr;
//    }

    @Override
    public JSONArray queryNextLine(String code, String plan_uuid) {
        List<RouteLine> routeLineList= new LambdaQueryChainWrapper<>(routeLineMapper)
                .eq(RouteLine::getIs_active,"1")
                .eq(RouteLine::getDevice_code,code)
                .eq(RouteLine::getRoute_plan_id,plan_uuid)
                .list();
        JSONArray routeLineArr = JSONArray.parseArray(JSON.toJSONString(routeLineList));
        return routeLineArr;
    }

//    @Override
//    public RouteLineDto queryNextLineByWeight(String code, String plan_uuid) {
//        //通过起点找到所有的路由
//        //查询该起点终点的所有指令数量
//        //遍历
//
//        JSONArray arr = WQLObject.getWQLObject("acs_route_line").query(" is_active= '1' and  next_device_code = '" + code + "'and route_plan_id='" + plan_uuid + "'").getResultJSONArray(0);
//        List<JSONObject> list = new ArrayList();
//        for (int i = 0; i < arr.size(); i++) {
//            JSONObject oneobj = new JSONObject();
//
//            JSONObject json = arr.getJSONObject(i);
//            String device_code = json.getString("device_code");
//            String next_device_code = json.getString("next_device_code");
//            int weight = json.getInteger("weights");
//
//            JSONArray taskcount = WQLObject.getWQLObject("acs_task").query("start_point_code like '" + device_code
//                    + "%' and next_point_code like '" + next_device_code
//                    + "%' and task_status < 2 and is_delete='0' ").getResultJSONArray(0);
//
//            JSONArray instcount = WQLObject.getWQLObject("acs_instruction").query("start_point_code like '" + device_code
//                    + "%' and next_point_code like '" + next_device_code
//                    + "%' and instruction_status < 2 and is_delete='0' ").getResultJSONArray(0);
//
//            weight = weight + taskcount.size() + instcount.size();
//            oneobj.put("json", json);
//            oneobj.put("weight", weight);
//            list.add(oneobj);
//
//        }
//
//        Collections.sort(list,
//                new Comparator<JSONObject>() {
//                    @Override
//                    public int compare(JSONObject o1,
//                                       JSONObject o2) {
//                        return o1.getString("weight").compareTo(o2.getString("weight"));
//                    }
//                });
//
//        JSONObject json = list.get(0).getJSONObject("json");
//        final RouteLineDto obj = json.toJavaObject(RouteLineDto.class);
//
//        return obj;
//    }


//    @Override
//    public RouteLineDto querySuperiorLineByWeight(String code, String plan_uuid) {
//        //通过终点找到所有的路由
//        //查询该起点终点的所有指令数量
//        //遍历
//        JSONArray arr = WQLObject.getWQLObject("acs_route_line").query(" is_active= '1' and  next_device_code = '" + code + "'and route_plan_id='" + plan_uuid + "'").getResultJSONArray(0);
//        List<JSONObject> list = new ArrayList();
//        for (int i = 0; i < arr.size(); i++) {
//            JSONObject oneobj = new JSONObject();
//
//            JSONObject json = arr.getJSONObject(i);
//            String device_code = json.getString("device_code");
//            String next_device_code = json.getString("next_device_code");
//            int weight = json.getInteger("weights");
//
//
//            JSONArray taskcount = WQLObject.getWQLObject("acs_task").query("start_point_code like '" + device_code
//                    + "%' and next_point_code like '" + next_device_code
//                    + "%' and task_status < 2 and is_delete='0' ").getResultJSONArray(0);
//
//            JSONArray instcount = WQLObject.getWQLObject("acs_instruction").query("start_point_code like '" + device_code
//                    + "%' and next_point_code like '" + next_device_code
//                    + "%' and instruction_status < 2 and is_delete='0' ").getResultJSONArray(0);
//
//            weight = weight + taskcount.size() + instcount.size();
//            oneobj.put("json", json);
//            oneobj.put("weight", weight);
//            list.add(oneobj);
//
//        }
//
//        Collections.sort(list,
//                new Comparator<JSONObject>() {
//                    @Override
//                    public int compare(JSONObject o1,
//                                       JSONObject o2) {
//                        return o1.getString("weight").compareTo(o2.getString("weight"));
//                    }
//                });
//
//        JSONObject json = list.get(0).getJSONObject("json");
//        final RouteLineDto obj = json.toJavaObject(RouteLineDto.class);
//
//        return obj;
//    }

//    @Override
//    public RouteLineDto queryLineByPoint(String code1, String code2, String plan_uuid) {
//        WQLObject wo = WQLObject.getWQLObject("acs_route_line");
//        JSONObject json = wo.query("device_code ='" + code1 + "'" + " and next_device_code ='" + code2 + "'and route_plan_id='" + plan_uuid + "'").uniqueResult(0);
//        final RouteLineDto obj = json.toJavaObject(RouteLineDto.class);
//        return obj;
//    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Map whereJson) throws SQLException {
        ArrayList<String> start_arr = (ArrayList<String>) whereJson.get("device_code");
        ArrayList<String> next_arr = (ArrayList<String>) whereJson.get("next_device_code");
        for (int i = 0; i < start_arr.size(); i++) {
            String device_code = start_arr.get(i);
            for (int j = 0; j < next_arr.size(); j++) {
                String next_device_code = next_arr.get(j);
                RouteLineDto dto = new RouteLineDto();
                dto.setWeights(String.valueOf(whereJson.get("weights")));
                dto.setRoute_plan_id(String.valueOf(whereJson.get("route_plan_id")));
                dto.setDevice_code(device_code);
                dto.setNext_device_code(next_device_code);
                dto.setType(String.valueOf(whereJson.get("type")));
                String currentUsername = SecurityUtils.getCurrentUsername();
                String now = DateUtil.now();

                dto.setLine_uuid(IdUtil.simpleUUID());
                dto.setCreate_by(currentUsername);
                dto.setUpdate_by(currentUsername);
                dto.setUpdate_time(now);
                dto.setCreate_time(now);

//                WQLObject wo = WQLObject.getWQLObject("acs_route_line");
//                JSONObject json = (JSONObject) JSONObject.toJSON(dto);
                RouteLine entity = ConvertUtil.convert(dto, RouteLine.class);

                // 判断是否有重复的路由路线
//                JSONArray arr = wo.query("device_code = '" + dto.getDevice_code() + "' and next_device_code = '" + dto.getNext_device_code() + "'").getResultJSONArray(0);
                List<RouteLine>  list= new LambdaQueryChainWrapper<>(routeLineMapper)
                        .eq(RouteLine::getDevice_code,dto.getDevice_code())
                        .eq(RouteLine::getNext_device_code,dto.getNext_device_code())
                        .list();
                if (list.size() == 0) {
//                    wo.insert(json);
                    routeLineMapper.insert(entity);
                } else {
                    throw new BadRequestException("已存在该路由路线！");
                }
            }
        }
//        reload();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(RouteLineDto dto) throws SQLException {
        RouteLineDto entity = this.findById(dto.getLine_uuid());
        if (entity == null) throw new BadRequestException("被删除或无权限，操作失败!");

        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        dto.setUpdate_time(now);
        dto.setUpdate_by(currentUsername);

//        WQLObject wo = WQLObject.getWQLObject("acs_route_line");
//        JSONObject json = (JSONObject) JSONObject.toJSON(dto);
//
//        wo.update(json);

        RouteLine routeLine = ConvertUtil.convert(dto, RouteLine.class);
        routeLineMapper.updateById(routeLine);

        reload();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(String[] ids) throws SQLException {
        for (String line_uuid : ids) {
            this.removeById(line_uuid);
        }
        reload();
    }

    @Override
    public void download(List<RouteLineDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (RouteLineDto routeLine : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("设备编码", routeLine.getDevice_code());
            map.put("下一设备", routeLine.getNext_device_code());
            map.put("坐标值", routeLine.getWeights());
            map.put("points", routeLine.getPoints());
            map.put("路由方案标识", routeLine.getRoute_plan_id());
            map.put("备注", routeLine.getRemark());
            map.put("是否启用", routeLine.getIs_active());
            map.put("是否删除", routeLine.getIs_delete());
            map.put("创建者", routeLine.getCreate_by());
            map.put("创建时间", routeLine.getCreate_time());
            map.put("修改者", routeLine.getUpdate_by());
            map.put("修改时间", routeLine.getUpdate_time());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void enabled(String routeLineId, String ia_active) throws SQLException {
        //路由路线表【acs_route_line】
//        WQLObject.getWQLObject("acs_route_line");
        RouteLineDto dto = this.findById(routeLineId);
        dto.setIs_active(ia_active);
        this.update(dto);
    }

    @Override
    public void replaceAccess(String route_plan_id) {
        //获取所有设备 （主要是设备编号，可以修改）
        List<Device> deviceList= new LambdaQueryChainWrapper<>(deviceMapper)
                .list();
        JSONArray de = JSONArray.parseArray(JSON.toJSONString(deviceList));

        HashMap<String, Integer> map = new HashMap<>();
        for (int i = 0; i < de.size(); i++) {
            JSONObject jo = (JSONObject) de.get(i);
            map.put(jo.getString("device_code"), i);
        }
        int size = map.size();
        //查询所有路由
        List<RouteLine> routeLineList= new LambdaQueryChainWrapper<>(routeLineMapper)
                .eq(RouteLine::getRoute_plan_id,route_plan_id)
                .list();
        JSONArray route = JSONArray.parseArray(JSON.toJSONString(routeLineList));
        Map n[][] = new HashMap[size][size];
        //建二维数组
        for (int i = 0; i < route.size(); i++) {
            JSONObject jo = (JSONObject) route.get(i);
            String start = jo.getString("device_code");
            String end = jo.getString("next_device_code");
            if (ObjectUtil.isEmpty(map.get(start)) || ObjectUtil.isEmpty(map.get(end))) {//如果路由中的设备号在设备列表中找不到就跳过
                continue;
            }
            Integer s = Integer.valueOf(map.get(start));
            Integer e = Integer.valueOf(map.get(end));
            HashMap<String, String> smap = new HashMap<>();
            smap.put("device_code", start);
            smap.put("next_device_code", end);
            smap.put("type", jo.getString("type"));
            smap.put("path", start + "->" + end);
            smap.put("weights", jo.getString("weights"));
            smap.put("route_plan_id", jo.getString("route_plan_id"));
            n[s][e] = smap;
        }
        //对数组使用Floyd(弗洛伊德)算法，求出任意两个设备之间的最短距离，不通则为null
//        JSONObject json = WQLObject.getWQLObject("sys_param").query("code ='route'").uniqueResult(0);

        Param param = paramService.findByCode("route");
        if (ObjectUtil.isNotEmpty(param)){
            if (StrUtil.equals(param.getValue(), "1")) {
                floyd(n);
            }
        }

        //将不为null的路由放到集合中
        List<Map> maps = new ArrayList<>();
        for (int i = 0; i < n.length; i++) {
            for (int j = 0; j < n[i].length; j++) {
                if (n[i][j] != null) {
                    maps.add(n[i][j]);
                }
            }
        }

        //更新内存中的数据
        routeChart = n;
        deviceCoordinate = map;
        routePlansList = maps;
    }

    //floyd算法，将所有设备之间的最短路线计算出来，如果是null 则代表不通
    private static void floyd(Map[][] graph) {
        for (int i = 0; i < graph.length; i++) {//  floyd
            for (int j = 0; j < graph.length; j++) {
                for (int k = 0; k < graph.length; k++) {
                    if (graph[j][i] != null && graph[i][k] != null && j != k) {
                        int v1 = Integer.valueOf((String) graph[j][i].get("weights"));
                        int v2 = Integer.valueOf((String) graph[i][k].get("weights"));
                        String s1 = (String) graph[j][i].get("path");
                        String s2 = (String) graph[i][k].get("path");
                        String s3 = s2.substring(s2.indexOf("-"));
                        String end = s2.substring(s2.lastIndexOf(">") + 1);
                        if (graph[j][k] == null) {//最开始两点间不是直接通路，需要经过别的点
                            String device_code = s1.substring(0, s1.indexOf("-"));
                            HashMap<String, String> map = new HashMap<>();
                            map.put("device_code", device_code);//开始
                            map.put("next_device_code", end);//终点
                            map.put("weights", v1 + v2 + "");
                            map.put("type", (String) graph[j][i].get("type"));
                            map.put("route_plan_id", (String) graph[j][i].get("route_plan_id"));
                            map.put("path", s1 + s3);
                            graph[j][k] = map;
                        } else if (Integer.valueOf((String) graph[j][k].get("weights")) > v1 + v2) {
                            graph[j][k].put("weights", v1 + v2 + "");
                            graph[j][k].put("path", s1 + s3);
                            graph[j][k].put("next_device_code", end);
                        }

                    }

                }
            }
        }
    }

    @Override
    public boolean getReplaceAccess(String startDeviceCode, String endDeviceCode) {

        return false;
    }

    /**
     * 加载路由路线
     * @throws SQLException
     */
    @Override
    public void reload() throws SQLException {
        Object[] param = new Object[0];
        Map map = new HashMap();
        List<RoutePlanDto> routePlans = this.routePlanService.queryAll(map);
        Iterator var2 = routePlans.iterator();
        while (var2.hasNext()) {
            RoutePlanDto routePlan = (RoutePlanDto) var2.next();
            Map map1 = new HashMap();
            map1.put("route_plan_id", routePlan.getPlan_uuid());
            //List<Entity> allRouteLines = Db.use().query(initsql,param);

            /*long l = System.currentTimeMillis();
            List<Entity> allRouteLines = Db.use((DataSource) SpringContextHolder.getBean("dataSource")).query(initsql,param);
            long l1 = System.currentTimeMillis();
            System.out.println("加载时间"+(l1-l));*/

            replaceAccess(routePlan.getPlan_uuid());
            this.routePlans.put(routePlan.getPlan_code(), routePlan);

            /*List<RouteLineDto> routeDaoList = allRouteLines.stream().map(entity -> {
                RouteLineDto routeLineDto = new RouteLineDto();
                routeLineDto.setDevice_code(entity.get("device_code").toString());
                routeLineDto.setNext_device_code(entity.get("next_device_code").toString());
                routeLineDto.setRoute_plan_id(entity.get("route_plan_id").toString());
                routeLineDto.setType(entity.get("type").toString());
                routeLineDto.setPath(entity.get("path").toString());
                routeLineDto.setWeights(Integer.parseInt(entity.get("weights").toString()));
                return routeLineDto;
            }).collect(Collectors.toList());*/


            List<RouteLineDto> routeDaoList = routePlansList.stream().map(entity -> {
                RouteLineDto routeLineDto = new RouteLineDto();
                routeLineDto.setDevice_code(entity.get("device_code").toString());
                routeLineDto.setNext_device_code(entity.get("next_device_code").toString());
                routeLineDto.setRoute_plan_id(entity.get("route_plan_id").toString());
                routeLineDto.setType(entity.get("type").toString());
                routeLineDto.setPath(entity.get("path").toString());
                routeLineDto.setWeights(entity.get("weights").toString());
                return routeLineDto;
            }).collect(Collectors.toList());
            Iterator var = routeDaoList.iterator();
            List list = new ArrayList<>();

            while (var.hasNext()) {
                RouteLineDto routeLine = (RouteLineDto) var.next();

                if (StrUtil.equals(routePlan.getPlan_uuid(), routeLine.getRoute_plan_id())) {
                    list.add(routeLine);
                }
            }
            routeLines.put(routePlan.getPlan_code(), list);
        }


    }

    @Override
    public boolean checkRouteLine(String startDevice, String nextDevice, String plan_code) throws Exception {
        //判断起点终点设备类型
        String startDeviceType = deviceAppService.findDeviceTypeByCode(startDevice);
        String nextDeviceType = deviceAppService.findDeviceTypeByCode(nextDevice);

        //起点、终点都为货架 并且相同
        if (StrUtil.equals(DeviceType.storage.toString(), startDeviceType)
                && StrUtil.equals(DeviceType.storage.toString(), nextDeviceType)) {
            return true;
        } else {

            List<RouteLineDto> list = this.getShortPathLines(startDevice, nextDevice, plan_code);
            if (ObjectUtil.isEmpty(list)) {
                return false;
            }
        }

        return true;
    }

    @Override
    public Map<String, List> getRouteLines() {
        return routeLines;
    }

    @Override
    public List<RouteLineDto> getShortPathLines(String device_code, String next_device_code, String plan_code) {

        List list = this.routeLines.get(plan_code);
        List result = new ArrayList();
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            RouteLineDto routeLineDto = (RouteLineDto) iterator.next();
            if (StrUtil.equals(routeLineDto.getDevice_code(), device_code) &&
                    StrUtil.equals(routeLineDto.getNext_device_code(), next_device_code)) {
                result.add(routeLineDto);
            }
        }
        List<RouteLineDto> newresult = (List<RouteLineDto>) result.stream().sorted(Comparator.comparing(RouteLineDto::getWeights)).collect(Collectors.toList());
        return newresult;
    }

    @Override
    public List<RouteLineDto> getShortPathLinesByCode(String device_code, String plan_code) {
        List list = this.routeLines.get(plan_code);
        List result = new ArrayList();
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            RouteLineDto routeLineDto = (RouteLineDto) iterator.next();
            if (StrUtil.equals(routeLineDto.getDevice_code(), device_code)) {
                result.add(routeLineDto);
            }
        }
        List<RouteLineDto> newresult = (List<RouteLineDto>) result.stream().sorted(Comparator.comparing(RouteLineDto::getWeights)).collect(Collectors.toList());

        return newresult;
    }

    @Override
    public List<RouteLineDto> getPathLinesByCode(String device_code, String plan_code) {
        List list = this.routeLines.get(plan_code);
        List result = new ArrayList();
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            RouteLineDto routeLineDto = (RouteLineDto) iterator.next();
            if (StrUtil.equals(routeLineDto.getNext_device_code(), device_code)) {
                result.add(routeLineDto);
            }
        }
        List<RouteLineDto> newresult = (List<RouteLineDto>) result.stream().sorted(Comparator.comparing(RouteLineDto::getWeights)).collect(Collectors.toList());

        return newresult;
    }

    @Override
    public List<RouteLineDto> getSuperiorShortPathLinesByCode(String device_code, String plan_code) {
        List list = this.routeLines.get(plan_code);
        List result = new ArrayList();
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            RouteLineDto routeLineDto = (RouteLineDto) iterator.next();
            if (StrUtil.equals(routeLineDto.getNext_device_code(), device_code)) {
                result.add(routeLineDto);
            }
        }
        List<RouteLineDto> newresult = (List<RouteLineDto>) result.stream().sorted(Comparator.comparing(RouteLineDto::getWeights)).collect(Collectors.toList());
        return newresult;
    }


    @Override
    public void autoInitial() throws Exception {
        this.reload();
    }


    public int getSize() {
        return this.deviceAppService.findDeviceDriver(RouteableDeviceDriver.class).size();
    }

    public int getIndex(String device_code) {
        Iterator var2 = this.routeIndex.keySet().iterator();

        Integer i;
        do {
            if (!var2.hasNext()) {
                throw new BadRequestException(device_code + "当前设备没有路由请检查设备配置");
            }

            i = (Integer) var2.next();
        } while (!((String) this.routeIndex.get(i)).equals(device_code));

        return i;
    }


    public String getDeviceCode(int index) {
        return (String) this.routeIndex.get(index);
    }

    @Override
    public JSONArray getActivePathLine(String device_code, String next_device_code, String plan_code) {
        QueryWrapper<RouteLine> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(device_code),"line.device_code",device_code);
        wrapper.eq(StringUtils.isNotBlank(next_device_code),"line.next_device_code ",next_device_code);
        wrapper.eq(StringUtils.isNotBlank(plan_code),"plan.plan_code",plan_code);
        wrapper.eq("line.is_active","1");
        List<RouteLine> routeLineList = routeLineMapper.selectRouteLineList(wrapper);
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(routeLineList));
        return jsonArray;
    }
}
