package com.foreverwin.mesnac.quartz.service.impl;

import cn.hutool.core.util.StrUtil;
import com.foreverwin.mesnac.quartz.constant.Constants;
import com.foreverwin.mesnac.quartz.dto.SystemJobDTO;
import com.foreverwin.mesnac.quartz.mapper.SystemJobMapper;
import com.foreverwin.mesnac.quartz.model.SystemJob;
import com.foreverwin.mesnac.quartz.service.SystemJobService;
import com.foreverwin.mesnac.quartz.util.ScheduleUtil;
import com.foreverwin.modular.core.util.CommonMethods;
import com.foreverwin.modular.core.util.FrontPage;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.quartz.Scheduler;
import org.quartz.impl.matchers.KeyMatcher;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 系统任务表 服务实现类
 * </p>
 *
 * @author Ervin Chen
 * @since 2020-10-21
 */
@Service
//@Transactional(rollbackFor = Exception.class)
public class SystemJobServiceImpl extends ServiceImpl<SystemJobMapper, SystemJob> implements SystemJobService {

    @Autowired(required = false)
    Scheduler scheduler;

    @Autowired
    private SystemJobMapper systemJobMapper;

    @Override
    public IPage<SystemJob> selectPage(FrontPage<SystemJob> frontPage, SystemJob systemJob) {
        QueryWrapper<SystemJob> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(systemJob);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<SystemJob> selectList(SystemJob systemJob) {
        QueryWrapper<SystemJob> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(systemJob);
        return super.list(queryWrapper);
    }

    @Override
    public List<SystemJobDTO> listSystemJob() {
        return baseMapper.selectSystemJobList();
    }

    @Override
    public IPage<SystemJobDTO> pageSystemJob(FrontPage<SystemJobDTO> frontPage, SystemJobDTO jobDTO) {
        QueryWrapper<SystemJobDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(jobDTO);
        if (frontPage.getGlobalQuery() != null && !"".equals(frontPage.getGlobalQuery().trim())) {
            queryWrapper.lambda().and(wrapper -> wrapper
                    .like(SystemJobDTO::getHandle, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getSite, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getName, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getDescription, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getJobGroup, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getJobClass, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getJobParam, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getRemark, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getCreateUserBo, frontPage.getGlobalQuery())
                    .or().like(SystemJobDTO::getUpdateUserBo, frontPage.getGlobalQuery())
            );
        }
        return baseMapper.selectPageSystemJob(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public boolean save(SystemJobDTO jobDTO) {
        //创建schedule任务
        String site = CommonMethods.getSite();
        String name = jobDTO.getName();
        String group = jobDTO.getJobGroup();
        String jobClass = jobDTO.getJobClass();
        String cronExpression = jobDTO.getCronExpression();
        String description = jobDTO.getDescription();
        String param = jobDTO.getJobParam();
        Map<String,Object> jobParam = mapOfTaskParam(jobDTO.getJobParam());
        ScheduleUtil.createScheduleJob(scheduler, name, jobClass, group, description, cronExpression, jobParam);
        //创建systemJob
        SystemJob systemJob = new SystemJob();
        systemJob.setHandle(String.format(Constants.SYSTEM_JOB_BO, site, group, name));
        systemJob.setSite(site);
        systemJob.setName(name);
        systemJob.setJobClass(jobClass);
        systemJob.setJobGroup(group);
        systemJob.setDescription(description);
        systemJob.setJobParam(param);
        systemJob.setCreatedDateTime(LocalDateTime.now());
        systemJob.setCreateUserBo(CommonMethods.getUserBo());
        baseMapper.insert(systemJob);

        return true;
    }

    @Override
    public boolean updateById(SystemJobDTO jobDTO) {
        //修改schedule任务
        String site = CommonMethods.getSite();
        String name = jobDTO.getName();
        String group = jobDTO.getJobGroup();
        String jobClass = jobDTO.getJobClass();
        String cronExpression = jobDTO.getCronExpression();
        String description = jobDTO.getDescription();
        String param = jobDTO.getJobParam();
        Map<String,Object> jobParam = mapOfTaskParam(jobDTO.getJobParam());
        //先删除原有schedulejob确保jobParam更新为最新
        ScheduleUtil.deleteScheduleJob(scheduler, name, group);
        ScheduleUtil.createScheduleJob(scheduler, name, jobClass, group, description, cronExpression, jobParam);

        //修改systemJob
        SystemJob systemJob = baseMapper.selectById(jobDTO.getHandle());
        systemJob.setHandle(String.format(Constants.SYSTEM_JOB_BO, site, group, name));
        systemJob.setName(name);
        systemJob.setJobClass(jobClass);
        systemJob.setJobGroup(group);
        systemJob.setDescription(description);
        systemJob.setJobParam(param);
        systemJob.setUpdatedDateTime(LocalDateTime.now());
        systemJob.setUpdateUserBo(CommonMethods.getUserBo());
        baseMapper.updateById(systemJob);
        return true;
    }

    @Override
    public boolean removeById(Serializable id){
        //删除schedule任务
        SystemJob systemJob = baseMapper.selectById(id);
        String name = systemJob.getName();
        String group = systemJob.getJobGroup();
        ScheduleUtil.deleteScheduleJob(scheduler, name, group);

        //删除Migration task
        baseMapper.deleteById(id);
        return true;
    }


    @Override
    public boolean pause(Serializable id) {
        SystemJob systemJob = baseMapper.selectById(id);
        String name = systemJob.getName();
        String group = systemJob.getJobGroup();
        ScheduleUtil.pauseScheduleJob(scheduler, name, group);
        return true;
    }

    @Override
    public boolean resume(Serializable id) {
        SystemJob systemJob = baseMapper.selectById(id);
        String name = systemJob.getName();
        String group = systemJob.getJobGroup();
        ScheduleUtil.resumeScheduleJob(scheduler, name, group);
        return true;
    }

    public Map<String,Object> mapOfTaskParam(String taskParam){
        Map<String,Object> paramMap = new HashMap<>();
        if(StrUtil.isBlank(taskParam)){
            return paramMap;
        }
        List<String> list = StrUtil.splitTrim(taskParam, "\n");
        for(String exp : list){
            List<String> sublist = StrUtil.splitTrim(exp, "=");
            if(sublist.size() > 1){
                paramMap.put(sublist.get(0), sublist.get(1));
            }
        }
        return paramMap;
    }

}