package com.artfess.cqlt.task.manager.impl;

import com.artfess.base.exception.RequiredException;
import com.artfess.base.jdbc.JdbcDaoImpl;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.cqlt.task.dao.SchedulerTaskDao;
import com.artfess.cqlt.task.manager.SchedulerTaskManager;
import com.artfess.cqlt.task.model.SchedulerTask;
import com.artfess.job.persistence.manager.SchedulerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 计算模型调度任务信息 服务实现类
 *
 * @company 阿特菲斯信息技术有限公司
 * @author chens
 * @since 2021-12-16
 */
@Service
public class SchedulerTaskManagerImpl extends BaseManagerImpl<SchedulerTaskDao, SchedulerTask> implements SchedulerTaskManager {


    @Resource
    SchedulerService schedulerService;
    @Resource
    Scheduler scheduler;
    @Resource
    JdbcDaoImpl jdbcDaoImpl;

    @Override
    public PageList<SchedulerTask> sliceQuerySchedulerTask(QueryFilter<SchedulerTask> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        IPage<SchedulerTask> result=baseMapper.sliceQuerySchedulerTask(convert2IPage(pageBean), convert2Wrapper(queryFilter, currentModelClass()));
        return new PageList<SchedulerTask>(result);
    }

    @Override
    @Transactional
    public boolean insertSchedulerTask(SchedulerTask schedulerTask) {
        if (BeanUtils.isNotEmpty(schedulerTask)){

            if(StringUtil.isEmpty(schedulerTask.getTaskName())){
                throw new RequiredException("添加数据抽取任务失败，请填写任务名称！");
            }
            if(StringUtil.isEmpty(schedulerTask.getTaskClass())){
                throw new RequiredException("添加数据抽取任务失败，请填写任务执行类的全名称！");
            }
            if(schedulerTask.getTaskRate()==null || schedulerTask.getTaskRate()<=0 || StringUtil.isEmpty(schedulerTask.getTaskRateUnit())){
                throw new RequiredException("添加数据抽取任务失败，请填写执行频率！");
            }

            if(checkSameCode(schedulerTask.getTaskName(),schedulerTask.getId())){
                throw new RequiredException("添加数据抽取任务失败，该任务【"+schedulerTask.getTaskName()+"】在系统中已存在，不能重复！");
            }
            schedulerTask.setTaskStatus("NONE");
            Integer result = this.baseMapper.insert(schedulerTask);
            return null != result && result >= 1;
        }else{
            return false;
        }
    }

    @Override
    @Transactional
    public boolean updateSchedulerTask(SchedulerTask schedulerTask) throws SchedulerException{
        if (BeanUtils.isNotEmpty(schedulerTask)){
            SchedulerTask oldModelTask = this.baseMapper.selectById(schedulerTask.getId());
            if("NORMAL".equals(oldModelTask.getTaskStatus())){
                throw new RequiredException("修改数据抽取任务失败，任务正在运行，请先停止！");
            }

            if(StringUtil.isEmpty(schedulerTask.getTaskName())){
                throw new RequiredException("修改数据抽取任务失败，请填写任务名称！");
            }
            if(StringUtil.isEmpty(schedulerTask.getTaskClass())){
                throw new RequiredException("修改数据抽取任务失败，请填写任务执行类的全名称！");
            }
            if(schedulerTask.getTaskRate()==null || schedulerTask.getTaskRate()<=0 || StringUtil.isEmpty(schedulerTask.getTaskRateUnit())){
                throw new RequiredException("修改数据抽取任务失败，请填写执行频率！");
            }

            if(checkSameCode(schedulerTask.getTaskName(),schedulerTask.getId())){
                throw new RequiredException("修改数据抽取任务失败，该任务【"+schedulerTask.getTaskName()+"】在系统中已存在，不能重复！");
            }
            //先删除暂停的JOB任务
            delJob(schedulerTask.getId());

            Integer result = this.baseMapper.updateById(schedulerTask);
            return null != result && result >= 1;
        }else{
            return false;
        }
    }

    @Override
    @Transactional
    public boolean deleteSchedulerTaskById(String id) throws SchedulerException{
        if(StringUtil.isEmpty(id)){
            throw new RequiredException("删除数据抽取任务失败，请选择要删除的任务！");
        }
        SchedulerTask oldModelTask = this.baseMapper.selectById(id);
        if("NORMAL".equals(oldModelTask.getTaskStatus())){
            throw new RequiredException("删除数据抽取任务失败，任务正在运行，请先停止！");
        }
        delJob(id);
        Integer result = this.baseMapper.deleteById(id);
        return null != result && result >= 1;
    }

    @Override
    @Transactional
    public boolean startUpJob(String taskId) throws SchedulerException {
        if(StringUtil.isEmpty(taskId)){
            return false;
        }
        SchedulerTask schedulerTask = this.baseMapper.selectById(taskId);
        String keyName = schedulerTask.getTaskName()+":"+ scheduler.getSchedulerName();
        String className = schedulerTask.getTaskClass(); //定时任务处理类的路径
        Map<String, Object> parameterMap=new HashMap<>();//定时任务处理类所需的参数
        parameterMap.put("id",taskId);

        boolean isExist = schedulerService.isJobExists(keyName); //判断是否存在定时任务
        if(!isExist) {
            schedulerService.addJob(keyName, className, parameterMap, schedulerTask.getTaskName());//添加定时任务
        }
        if(schedulerTask.getTaskType()==1){
            boolean rtn = schedulerService.isTriggerExists(keyName);//判断是否存在定时任务的触发器
            if (!rtn) {
                schedulerService.addTrigger(keyName, keyName, schedulerTask.getTaskRate(), schedulerTask.getTaskRateUnit()); //添加触发器
            }else{
                Trigger.TriggerState state = schedulerService.getTriggerState(keyName);//判断定时器状态
                if (state == Trigger.TriggerState.PAUSED) {
                    schedulerService.resumeTrigger(keyName); //启动定时器
                }
            }
        }else{
            boolean rtn = schedulerService.isTriggerExists(keyName);//判断是否存在定时任务的触发器
            if (!rtn) {
                schedulerService.addSimpleTrigger(keyName, keyName); //添加触发器
            }else{
                Trigger.TriggerState state = schedulerService.getTriggerState(keyName);//判断定时器状态
                if (state == Trigger.TriggerState.PAUSED) {
                    schedulerService.resumeTrigger(keyName); //启动定时器
                }
            }
        }

        //schedulerTask.setJobName(keyName);
        schedulerTask.setTaskStatus("NORMAL");
        this.baseMapper.updateById(schedulerTask);
        return true;
    }

    @Override
    @Transactional
    public boolean stopJob(String taskId) throws SchedulerException {
        if(StringUtil.isEmpty(taskId)){
            return false;
        }
        SchedulerTask schedulerTask = this.baseMapper.selectById(taskId);
        String keyName = schedulerTask.getTaskName()+":"+ scheduler.getSchedulerName();
        Trigger.TriggerState state = schedulerService.getTriggerState(keyName);
        if (state == Trigger.TriggerState.NORMAL) {
            schedulerService.pauseTrigger(keyName);
        }
        schedulerTask.setTaskStatus("PAUSED");
        this.baseMapper.updateById(schedulerTask);
        return true;
    }

    @Override
    @Transactional
    public boolean delJob(String taskId) throws SchedulerException {
        if(StringUtil.isEmpty(taskId)){
            return false;
        }
        SchedulerTask schedulerTask = this.baseMapper.selectById(taskId);
        String keyName = schedulerTask.getTaskName()+":"+ scheduler.getSchedulerName();
        boolean rtn = schedulerService.isTriggerExists(keyName);//判断是否存在定时任务的触发器
        if(rtn) {
            schedulerService.delTrigger(keyName);
        }
        boolean isExist = schedulerService.isJobExists(keyName);
        if(isExist) {
            schedulerService.delJob(keyName);
        }
        schedulerTask.setTaskStatus("NONE");
        this.baseMapper.updateById(schedulerTask);
        return true;
    }



    private boolean checkSameCode(String taskName,String id){
        Assert.hasText(taskName, "任务名称不能为空。");
        QueryWrapper<SchedulerTask> queryWrapper = new QueryWrapper<SchedulerTask>();
        queryWrapper.eq( "task_name_", taskName);
        queryWrapper.ne(StringUtil.isNotEmpty(id), "ID_", id);
        int num = this.baseMapper.selectCount(queryWrapper);
        if(num != 0){
            return true;
        }else {
            return false;
        }
    }
}
