package com.usky.rule.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.rule.cache.DeviceTriggerIncludeMinuteCache;
import com.usky.rule.config.CronTaskManager;
import com.usky.rule.domain.*;
import com.usky.rule.enums.ActionTypeEnum;
import com.usky.rule.enums.ConstraintTypeEnum;
import com.usky.rule.enums.TriggerTypeEnum;
import com.usky.rule.exception.BizException;
import com.usky.rule.mapper.RuleEngineCronMapper;
import com.usky.rule.mapper.RuleEngineDeviceMapper;
import com.usky.rule.mapper.RuleEngineLogMapper;
import com.usky.rule.mapper.RuleEngineMapper;
import com.usky.rule.service.*;
import com.usky.rule.util.CronUtil;
import com.usky.rule.util.JsonUtil;
import com.usky.rule.vo.*;
import com.usky.rule.vo.action.AlarmEventAction;
import com.usky.rule.vo.action.DeviceControlAction;
import com.usky.rule.vo.action.RuleEngineAction;
import com.usky.rule.vo.constraint.CronConstraint;
import com.usky.rule.vo.constraint.DeviceConstraint;
import com.usky.rule.vo.trigger.CronTrigger;
import com.usky.rule.vo.trigger.DeviceTrigger;
import com.usky.rule.vo.trigger.SpaceTrigger;
import com.usky.rule.vo.visualization.SimpleVO;
import feign.Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RuleEngineServiceImpl extends AbstractCrudService<RuleEngineMapper, RuleEngine> implements RuleEngineService {
    private final RuleEngineCronService ruleEngineCronService;
    private final RuleEngineDeviceService ruleEngineDeviceService;
    private static final Map<String, Class<?>> triggerMap = new HashMap();
    private static final Map<String, Class<?>> constraintMap = new HashMap();
    private static final Map<String, Class<?>> actionMap = new HashMap();
//    @Autowired
//    private RuleEngineLogService ruleEngineLogService;
    @Autowired
    private RuleEngineCronMapper ruleEngineCronMapper;
    @Autowired
    private RuleEngineDeviceMapper ruleEngineDeviceMapper;
    @Autowired
    private DeviceTriggerIncludeMinuteCache deviceTriggerIncludeMinuteCache;

    private final CronTaskManager cronTaskManager;
    @Lazy
    @Autowired
    private RuleEngineDetailService ruleEngineDetailService;
    @Autowired
    private BaseSpaceService baseSpaceService;

    public RuleEngineServiceImpl(RuleEngineCronService ruleEngineCronService, RuleEngineDeviceService ruleEngineDeviceService,
                                 @Lazy CronTaskManager cronTaskManager) {
        this.ruleEngineCronService = ruleEngineCronService;
        this.ruleEngineDeviceService = ruleEngineDeviceService;
        this.cronTaskManager = cronTaskManager;
    }



    @PostConstruct
    public void init() {

        triggerMap.put(TriggerTypeEnum.CRON.getType(), CronTrigger.class);
        triggerMap.put(TriggerTypeEnum.DEVICE.getType(), DeviceTrigger.class);
        triggerMap.put(TriggerTypeEnum.SPACE.getType(), SpaceTrigger.class);
        constraintMap.put(ConstraintTypeEnum.CRON.getType(), CronConstraint.class);
        constraintMap.put(ConstraintTypeEnum.DEVICE.getType(), DeviceConstraint.class);
        actionMap.put(ActionTypeEnum.ALARM_EVENT.getType(), AlarmEventAction.class);
//        actionMap.put(ActionTypeEnum.WORK_ORDER.getType(), WorkOrderAction.class);
        actionMap.put(ActionTypeEnum.DEVICE_CONTROL.getType(), DeviceControlAction.class);
    }

    @Override
    public void add(RuleEngine ruleEngine) {
        if (ruleEngine.getStatus() == null) {
            ruleEngine.setStatus(0);
        }
        ruleEngine.setCreatedBy(SecurityUtils.getUsername());
        ruleEngine.setTenantId(SecurityUtils.getTenantId());
        getBaseMapper().insert(ruleEngine);
    }

    @Override
    public void update(RuleEngine ruleEngine) {
        ruleEngine.setUpdatedBy(SecurityUtils.getUsername());
        getBaseMapper().updateById(ruleEngine);
    }

    /**
     * 删除规则（参考 leo RuleEngineDetailServiceImpl.remove）：
     * 1. 校验 id 非空
     * 2. 清理该规则下的 cron 任务数据（对应 leo cronTaskManager.deleteAllJobsInJobGroup）
     * 3. 清理该规则关联的设备绑定（对应 leo historyRecordCache.deleteConditions 的关联数据）
     * 4. 删除规则主表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("id不能为空");
        }

        deviceTriggerIncludeMinuteCache.deleteConditions(id);
        cronTaskManager.deleteAllJobsInJobGroup(id);
        ruleEngineCronMapper.deleteByRuleEngineId(id);
        ruleEngineDeviceMapper.deleteByRuleEngineId(id);
        getBaseMapper().deleteById(id);
    }

    @Override
    public RuleEngine getById(Long id) {
        Integer tenantId = SecurityUtils.getTenantId();
        if (tenantId == 0 || tenantId == null) {
            return getBaseMapper().selectById(id, null);
        }else{
            return getBaseMapper().selectById(id, SecurityUtils.getTenantId());
        }

    }

    /** 收集某空间下所有子孙空间 id（兼容 MySQL 5.7，在应用层递归） */
    private List<Long> collectAllDescendantSpaceIds(Long parentId) {
        List<Long> result = new ArrayList<>();
        List<Long> currentLevel = getBaseMapper().selectDirectChildrenSpaceIds(parentId);
        while (!currentLevel.isEmpty()) {
            result.addAll(currentLevel);
            List<Long> nextLevel = new ArrayList<>();
            for (Long id : currentLevel) {
                nextLevel.addAll(getBaseMapper().selectDirectChildrenSpaceIds(id));
            }
            currentLevel = nextLevel;
        }
        return result;
    }

    @Override
    public CommonPage<RuleEngine> pageList(RuleEnginePageRequest request) {
        List<Long> ids = new ArrayList();
        if (request.getSpaceId() != null) {
            ids.add(request.getSpaceId());
            ids.addAll(collectAllDescendantSpaceIds(request.getSpaceId()));
        }


        IPage<RuleEngine> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<RuleEngine> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(CollectionUtils.isNotEmpty(ids), RuleEngine::getSpaceId, ids)
                .like(StringUtils.isNotBlank(request.getName()),RuleEngine::getName, request.getName())
                .eq(request.getStatus() != null,RuleEngine::getStatus,request.getStatus())
                .eq(RuleEngine::getTenantId,SecurityUtils.getTenantId())
                .orderByDesc(RuleEngine::getId);
        page = this.page(page, queryWrapper);

        if(!page.getRecords().isEmpty()){
            List<Long> spaceIds = page.getRecords().stream().map(RuleEngine::getSpaceId).distinct().collect(Collectors.toList());
            List<BaseSpace> spaceList = baseSpaceService.listByIds(spaceIds);
            Map<Long, BaseSpace> spaceMap = (Map)spaceList.stream().collect(Collectors.toMap(BaseSpace::getId, (s) -> s));
            page.getRecords().forEach((r) -> r.setSpaceName(((BaseSpace)spaceMap.get(r.getSpaceId())).getName()));
        }

        return new CommonPage<>(page.getRecords(), page.getTotal(), request.getPageSize(), request.getPageNum());

    }

    @Override
    public List<RuleEngine> list(RuleEnginePageRequest request) {
        List<Long> ids = new ArrayList();
        if (request.getSpaceId() != null) {
            ids.add(request.getSpaceId());
            ids.addAll(collectAllDescendantSpaceIds(request.getSpaceId()));
        }

        LambdaQueryWrapper<RuleEngine> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(CollectionUtils.isNotEmpty(ids), RuleEngine::getSpaceId, ids)
                .like(StringUtils.isNotBlank(request.getName()),RuleEngine::getName, request.getName())
                .eq(request.getStatus() != null,RuleEngine::getStatus,request.getStatus())
                .eq(SecurityUtils.getTenantId() != 0 && SecurityUtils.getTenantId() != null,RuleEngine::getTenantId,SecurityUtils.getTenantId());
        List<RuleEngine> ruleEngines = this.list(queryWrapper);
        return ruleEngines;
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        LambdaQueryWrapper<RuleEngine> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(RuleEngine::getId, id)
                .eq(RuleEngine::getTenantId,SecurityUtils.getTenantId());
        RuleEngine engine = (RuleEngine)this.getOne(wrapper);
        RuleEngineDTO engineDTO = new RuleEngineDTO();
        engineDTO.setId(id);
        engineDTO.setStatus(engine.getStatus() == 1 ? 0 : 1);
        engineDTO.setProjectId(engine.getProjectId());
        engineDTO.setName(engine.getName());
        engineDTO.setDetail(engine.getDetail());
        getBaseMapper().updateStatus(id, status);

        ruleEngineDetailService.update(engineDTO);
    }

    @Override
    public List<RuleEngine> listEnabledByProjectId(Long projectId) {
        Integer tenantId = null;
        try {
            tenantId = SecurityUtils.getTenantId();
        } catch (Exception ignored) {
        }
        return getBaseMapper().selectEnabledByProjectId(projectId, tenantId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void ruleEngineConfig(RuleEngineDTO dto) {
        if (dto.getId() == null) {
            throw new BizException("id不能为空");
        }
        RuleEngine rule = this.getById(dto.getId());
        if (rule != null) {
            String detail = dto.getDetail();

            RuleEngineDetail ruleEngineDetail;
            rule.setDetail(detail);
            rule.setUpdateTime(LocalDateTime.now());
            try {
                ruleEngineDetail = JsonUtil.toObject(detail, RuleEngineDetail.class);
            } catch (Exception var13) {
                throw new BizException("json格式有误");
            }

            this.verifyJson(ruleEngineDetail);
            this.updateById(rule);

            Long ruleEngineId = rule.getId();
            Integer tenantId = rule.getTenantId();

            ruleEngineCronMapper.deleteByRuleEngineId(ruleEngineId);
            List<RuleEngineDetail.CommonVO> triggers = ruleEngineDetail.getTriggers();
            List<CronTrigger> cronTriggers = this.getCronTriggers(triggers);
            if (cronTriggers != null && !cronTriggers.isEmpty()) {
                cronTriggers.forEach((c) -> {
                    RuleEngineCron cron = new RuleEngineCron();
                    cron.setRuleEngineId(ruleEngineId);
                    cron.setCron(c.getCron().trim());
                    cron.setCreatedBy(rule.getCreatedBy());
                    cron.setUpdatedBy(rule.getUpdatedBy());
                    cron.setTenantId(tenantId);
                    ruleEngineCronMapper.insert(cron);
                });
            }

            ruleEngineDeviceMapper.deleteByRuleEngineId(ruleEngineId);
            List<DeviceTrigger> deviceTriggers = this.getDeviceTriggers(triggers);
            if (deviceTriggers != null && !deviceTriggers.isEmpty()) {
                deviceTriggers.forEach((c) -> {
                    List<SimpleVO> devices = c.getDevices();
                    List<Condition> conditionsList = c.getConditions();
                    devices.forEach((d) -> conditionsList.forEach((conditions) -> {
                        List<RuleEngineDevice> list = ruleEngineDeviceMapper.selectByDeviceAndIdentifier(d.getId(),conditions.getIdentifier(),ruleEngineId,null);
                        if (list != null && !list.isEmpty()) {
                            return;
                        }

                        RuleEngineDevice dev = new RuleEngineDevice();
                        dev.setRuleEngineId(ruleEngineId);
                        dev.setDeviceId(d.getId());
                        dev.setDeviceUuid(d.getDeviceUuid());
                        dev.setIdentifier(conditions.getIdentifier());
                        dev.setProductId(c.getProductId());
                        dev.setCreatedBy(rule.getCreatedBy());
                        dev.setUpdatedBy(rule.getUpdatedBy());
                        dev.setTenantId(tenantId);
                        ruleEngineDeviceMapper.insert(dev);
                    }));
                });
            }

            RuleEngineDTO engineDTO = new RuleEngineDTO();
            engineDTO.setId(rule.getId());
            engineDTO.setProjectId(rule.getProjectId());
            engineDTO.setName(rule.getName());
            engineDTO.setStatus(rule.getStatus());
            engineDTO.setDetail(rule.getDetail());
            ruleEngineDetailService.update(engineDTO);
        }

    }

    private void verifyJson(RuleEngineDetail ruleEngineDetail) {
        List<RuleEngineDetail.CommonVO> triggers = ruleEngineDetail.getTriggers();
        if (CollectionUtils.isNotEmpty(triggers)) {
            for(RuleEngineDetail.CommonVO vo : triggers) {
                this.triggerVerify(vo);
            }
        }

        List<RuleEngineDetail.CommonVO> constraints = ruleEngineDetail.getConstraints();
        if (CollectionUtils.isNotEmpty(constraints)) {
            for(RuleEngineDetail.CommonVO vo : constraints) {
                this.constraintVerify(vo);
            }
        }

        List<RuleEngineDetail.CommonVO> actions = ruleEngineDetail.getActions();
        if (CollectionUtils.isNotEmpty(actions)) {
            for(RuleEngineDetail.CommonVO vo : actions) {
                this.actionVerify(vo);
            }
        }

    }

    private void triggerVerify(RuleEngineDetail.CommonVO vo) {
        String type = vo.getType();
        String detail = vo.getDetail();
        if (Util.isBlank(detail)) {
            throw new BizException("触发条件不能为空");
        } else {
            if (TriggerTypeEnum.DEVICE.getType().equals(type)) {
                DeviceTrigger deviceTrigger = (DeviceTrigger)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, detail, DeviceTrigger.class);
                if (deviceTrigger.getProductId() == null) {
                    throw new BizException("触发条件-产品不能为空");
                }

                if (Util.isBlank(deviceTrigger.getMethod())) {
                    throw new BizException("触发条件-触发方式不能为空");
                }

                boolean flag = deviceTrigger.getMethod().equals("consumption");
                this.conditionsVerify(deviceTrigger.getConditions(), flag, "触发条件-");
                if (CollectionUtils.isEmpty(deviceTrigger.getDevices())) {
                    throw new BizException("触发条件-设备不能为空");
                }
            } else if (TriggerTypeEnum.CRON.getType().equals(type)) {
                CronTrigger cronTrigger = (CronTrigger)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, detail, CronTrigger.class);
                if (Util.isBlank(cronTrigger.getCron())) {
                    throw new BizException("触发条件-表达式不能为空");
                }

                if (!CronUtil.isCronMatched(cronTrigger.getCron())) {
                    throw new BizException("触发条件-表达式格式不正确");
                }
            } else if (TriggerTypeEnum.SPACE.getType().equals(type)) {
                SpaceTrigger spaceTrigger = (SpaceTrigger)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, detail, SpaceTrigger.class);
                if (Util.isBlank(spaceTrigger.getMethod())) {
                    throw new BizException("触发条件-触发方式不能为空");
                }

                if (CollectionUtils.isEmpty(spaceTrigger.getSpaces())) {
                    throw new BizException("触发条件-空间不能为空");
                }

                List<Condition> conditions = spaceTrigger.getConditions();
                if (CollectionUtils.isEmpty(spaceTrigger.getConditions())) {
                    throw new BizException("触发条件-触发方式不能为空");
                }

                for(int i = 0; i < conditions.size(); ++i) {
                    Condition condition = (Condition)conditions.get(i);
                    if (Util.isBlank(condition.getItemCode())) {
                        throw new BizException("触发条件-能源分项不能为空");
                    }

                    TimeRange timeRange = condition.getTimeRange();
                    if (timeRange.getStart() == null || timeRange.getEnd() == null) {
                        throw new BizException("触发条件-开始或结束时间不能为空");
                    }

                    Expression expression = condition.getExpression();
                    if (expression == null) {
                        throw new BizException("触发条件-限制条件不能为空");
                    }

                    if (i > 0 && Util.isBlank(condition.getOperator())) {
                        throw new BizException("触发条件-逻辑符不能为空");
                    }
                }
            }

        }
    }

    private void constraintVerify(RuleEngineDetail.CommonVO vo) {
        String type = vo.getType();
        String detail = vo.getDetail();
        if (Util.isBlank(detail)) {
            throw new BizException("约束条件不能为空");
        } else {
            if (type.equals(ConstraintTypeEnum.CRON.getType())) {
                CronConstraint cronConstraint = (CronConstraint)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, detail, CronConstraint.class);
                if (Util.isBlank(cronConstraint.getCron())) {
                    throw new BizException("约束条件-表达式不能为空");
                }

                if (!CronUtil.isCronMatched(cronConstraint.getCron())) {
                    throw new BizException("约束条件-表达式格式不正确");
                }
            } else if (type.equals(ConstraintTypeEnum.DEVICE.getType())) {
                DeviceConstraint deviceConstraint = (DeviceConstraint)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, detail, DeviceConstraint.class);
                if (deviceConstraint.getProductId() == null) {
                    throw new BizException("约束条件-产品不能为空");
                }

                if (CollectionUtils.isEmpty(deviceConstraint.getDevices())) {
                    throw new BizException("约束条件-设备不能为空");
                }

                this.conditionsVerify(deviceConstraint.getConditions(), false, "约束条件-");
            }

        }
    }

    private void actionVerify(RuleEngineDetail.CommonVO vo) {
        String type = vo.getType();
        String detail = vo.getDetail();
        if (Util.isBlank(detail)) {
            throw new BizException("执行动作不能为空");
        } else {
            if (ActionTypeEnum.DEVICE_CONTROL.getType().equals(type)) {
                DeviceControlAction deviceControlAction = (DeviceControlAction)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, detail, DeviceControlAction.class);
                if (deviceControlAction.getProductId() == null) {
                    throw new BizException("执行动作-产品不能为空");
                }

                List<DeviceControlAction.Functions> functionsList = deviceControlAction.getFunctions();
                if (CollectionUtils.isEmpty(functionsList)) {
                    throw new BizException("执行动作-动作不能为空");
                }

                List<SimpleVO> devices = deviceControlAction.getDevices();
                if (CollectionUtils.isEmpty(devices)) {
                    throw new BizException("执行动作-设备不能为空");
                }
            }

        }
    }

    private void conditionsVerify(List<Condition> conditionList, boolean flag, String name) {
        if (CollectionUtils.isEmpty(conditionList)) {
            throw new BizException(name + "功能点及条件不能为空");
        } else {
            for(int i = 0; i < conditionList.size(); ++i) {
                Condition condition = (Condition)conditionList.get(i);
                if (i > 0 && Util.isBlank(condition.getOperator())) {
                    throw new BizException(name + "逻辑符不能为空");
                }

                if (Util.isBlank(condition.getIdentifier())) {
                    throw new BizException(name + "功能点不能为空");
                }

                if (flag) {
                    TimeRange timeRange = condition.getTimeRange();
                    if (timeRange.getStart() == null || timeRange.getEnd() == null) {
                        throw new BizException(name + "开始或结束时间不能为空");
                    }
                }

                Expression expression = condition.getExpression();
                if (Util.isBlank(expression.getX()) && Util.isBlank(expression.getY()) && Util.isBlank(expression.getM())) {
                    throw new BizException(name + "限制条件不能为空");
                }
            }

        }
    }


    @Override
    public RuleEngineConfigDTO getEngineConfig(Long ruleEngineId) {
        RuleEngine rule = getBaseMapper().selectById(ruleEngineId, SecurityUtils.getTenantId());
        if (rule == null) {
            return null;
        }
        RuleEngineConfigDTO dto = new RuleEngineConfigDTO();
        dto.setRule(rule);
        List<String> cronExprs = ruleEngineCronMapper.selectByRuleEngineId(ruleEngineId).stream()
                .map(RuleEngineCron::getCron).collect(Collectors.toList());
        dto.setCronExprs(cronExprs);
        List<RuleEngineConfigDTO.RuleEngineDeviceItem> devices = new ArrayList<>();
        for (RuleEngineDevice dev : ruleEngineDeviceMapper.selectByRuleEngineId(ruleEngineId)) {
            RuleEngineConfigDTO.RuleEngineDeviceItem item = new RuleEngineConfigDTO.RuleEngineDeviceItem();
            item.setDeviceId(dev.getDeviceId());
            item.setDeviceUuid(dev.getDeviceUuid());
            item.setIdentifier(dev.getIdentifier());
            item.setProductId(dev.getProductId());
            devices.add(item);
        }
        dto.setDevices(devices);
        return dto;
    }

    @Override
    public void manualTrigger(Long ruleEngineId) {
        RuleEngine rule = getBaseMapper().selectById(ruleEngineId, SecurityUtils.getTenantId());
        if (rule == null) {
            throw new IllegalArgumentException("规则不存在: " + ruleEngineId);
        }

        if(!ruleEngineDetailService.manualPerformDeviceControl(ruleEngineId)){
            throw new BizException("触发未成功");
        }
    }

    @Override
    public void triggerByCron(Long ruleEngineId) {
        RuleEngine rule = getBaseMapper().selectById(ruleEngineId, SecurityUtils.getTenantId());
        if (rule == null) {
            return;
        }
    }


    public List<CronTrigger> getCronTriggers(List<RuleEngineDetail.CommonVO> commonVOList) {
        if (commonVOList != null && !commonVOList.isEmpty()) {
            List<CronTrigger> cronTriggerList = new ArrayList();
            Class<?> clazz = (Class)triggerMap.get(TriggerTypeEnum.CRON.getType());
            commonVOList.forEach((commonVO) -> {
                if (TriggerTypeEnum.CRON.getType().equals(commonVO.getType())) {
                    cronTriggerList.add((CronTrigger)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, commonVO.getDetail(), clazz));
                }

            });
            return cronTriggerList;
        } else {
            return null;
        }
    }

    public List<DeviceTrigger> getDeviceTriggers(List<RuleEngineDetail.CommonVO> commonVOList) {
        if (commonVOList != null && !commonVOList.isEmpty()) {
            List<DeviceTrigger> deviceTriggerList = new ArrayList();
            Class<?> clazz = (Class)triggerMap.get(TriggerTypeEnum.DEVICE.getType());
            commonVOList.forEach((commonVO) -> {
                if (TriggerTypeEnum.DEVICE.getType().equals(commonVO.getType())) {
                    deviceTriggerList.add((DeviceTrigger)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, commonVO.getDetail(), clazz));
                }

            });
            return deviceTriggerList;
        } else {
            return null;
        }
    }

    public List<SpaceTrigger> getSpaceTriggers(List<RuleEngineDetail.CommonVO> commonVOList) {
        if (commonVOList != null && !commonVOList.isEmpty()) {
            List<SpaceTrigger> deviceTriggerList = new ArrayList();
            Class<?> clazz = (Class)triggerMap.get(TriggerTypeEnum.SPACE.getType());
            commonVOList.forEach((commonVO) -> {
                if (TriggerTypeEnum.SPACE.getType().equals(commonVO.getType())) {
                    deviceTriggerList.add((SpaceTrigger)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, commonVO.getDetail(), clazz));
                }

            });
            return deviceTriggerList;
        } else {
            return null;
        }
    }

    public List<CronConstraint> getCronConstraints(List<RuleEngineDetail.CommonVO> commonVOList) {
        if (commonVOList != null && !commonVOList.isEmpty()) {
            List<CronConstraint> cronConstraintList = new ArrayList();
            Class<?> clazz = (Class)constraintMap.get(ConstraintTypeEnum.CRON.getType());
            commonVOList.forEach((commonVO) -> {
                if (ConstraintTypeEnum.CRON.getType().equals(commonVO.getType())) {
                    cronConstraintList.add((CronConstraint)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, commonVO.getDetail(), clazz));
                }

            });
            return cronConstraintList;
        } else {
            return null;
        }
    }

    public List<DeviceConstraint> getDeviceConstraints(List<RuleEngineDetail.CommonVO> commonVOList) {
        if (commonVOList != null && !commonVOList.isEmpty()) {
            List<DeviceConstraint> deviceConstraintList = new ArrayList();
            Class<?> clazz = (Class)constraintMap.get(ConstraintTypeEnum.DEVICE.getType());
            commonVOList.forEach((commonVO) -> {
                if (ConstraintTypeEnum.DEVICE.getType().equals(commonVO.getType())) {
                    deviceConstraintList.add((DeviceConstraint)JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, commonVO.getDetail(), clazz));
                }

            });
            return deviceConstraintList;
        } else {
            return null;
        }
    }

    public List<RuleEngineAction> getActions(List<RuleEngineDetail.CommonVO> commonVOList) {
        if (commonVOList != null && !commonVOList.isEmpty()) {
            List<RuleEngineAction> actionList = new ArrayList();
            commonVOList.forEach((commonVO) -> {
                if (ActionTypeEnum.ALARM_EVENT.getType().equals(commonVO.getType())) {
                    actionList.add(JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, commonVO.getDetail(), AlarmEventAction.class));
                }  else if (ActionTypeEnum.DEVICE_CONTROL.getType().equals(commonVO.getType())) {
                    actionList.add(JsonUtil.toObject(JsonUtil.IGNORE_UNKNOWN_PROPERTIES_JSON_MAPPER, commonVO.getDetail(), DeviceControlAction.class));
                }

            });
            return actionList;
        } else {
            return null;
        }
    }

    @Override
    public String getName(Long ruleEngineId) {
        RuleEngine ruleEngine = getBaseMapper().selectById(ruleEngineId);
        return ruleEngine == null ? "" : ruleEngine.getName();
    }

    @Override
    public String getDetail(Long ruleEngineId) {
        RuleEngine ruleEngine = getBaseMapper().selectById(ruleEngineId);
        return ruleEngine == null ? "" : ruleEngine.getDetail();
    }
}
