package cn.estsh.i3plus.core.apiservice.controller.busi;

import cn.estsh.i3plus.core.api.iservice.busi.ISysTaskCycleService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysTaskPlanService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysTaskService;
import cn.estsh.i3plus.icloud.wms.sdk.IWmsScheduleJobCloud;
import cn.estsh.i3plus.platform.common.util.PlatformConstWords;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.SysTask;
import cn.estsh.i3plus.pojo.platform.bean.SysTaskCycle;
import cn.estsh.i3plus.pojo.platform.bean.SysTaskPlan;
import cn.estsh.impp.framework.base.controller.CoreBaseController;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.exception.ImppExceptionEnum;
import cn.estsh.impp.framework.boot.quartz.IQuartzJobService;
import cn.estsh.impp.framework.boot.quartz.ScheduleTool;
import cn.estsh.impp.framework.boot.util.ResultBean;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Description : 任务计划管理服务
 * @Reference   :
 * @Author      : yunhao
 * @Date        : 2018-12-27 10:45
 * @Modify      :
 **/
@RestController
@Api(description = "任务计划管理服务")
@RequestMapping(PlatformConstWords.BASE_URL +"/task-plan")
public class SysTaskPlanController extends CoreBaseController{

    public static final Logger LOGGER = LoggerFactory.getLogger(SysTaskPlanController.class);

    @Autowired
    private ISysTaskPlanService sysTaskPlanService;

    @Autowired
    private ISysTaskCycleService sysTaskCycleService;

    @Autowired
    private ISysTaskService sysTaskService;

    /************ 微服定时任务 *********/
    @Autowired
    private ScheduleTool scheduleTool;

    @Autowired
    private IWmsScheduleJobCloud wmsScheduleJobCloud;

    /**
     * 根据来源切换定时任务服务
     * @param source CommonEnumUtil.SOFT_TYPE
     * @return
     */
    private IQuartzJobService getJobService(int source){
        IQuartzJobService quartzJobService = scheduleTool;

        if(source == CommonEnumUtil.SOFT_TYPE.CORE.getValue()){
            //平台定时任务
            quartzJobService = scheduleTool;
        }else if(source == CommonEnumUtil.SOFT_TYPE.WMS.getValue()){
            quartzJobService = wmsScheduleJobCloud;
        }
        return quartzJobService;
    }

    @PostMapping(value = "/insert")
    @ApiOperation(value = "新增任务计划", notes = "任务计划")
    public ResultBean insertSysTaskTime(SysTaskPlan sysTaskPlan, Boolean isExecute) {
        try {
            // 数据校验
            ValidatorBean.beginValid(sysTaskPlan)
                    .notNull("name", sysTaskPlan.getName())
                    .notNull("groupName",sysTaskPlan.getGroupName())
                    .notNull("taskCycleId",sysTaskPlan.getTaskCycleId())
                    .notNull("taskId",sysTaskPlan.getTaskId())
                    .notNull("taskMethodType", sysTaskPlan.getTaskMethodType());

            SysTaskCycle sysTaskCycle = sysTaskCycleService.getSysTaskCycleById(sysTaskPlan.getTaskCycleId());
            ValidatorBean.checkNotNull(sysTaskCycle,"任务周期不存在");

            SysTask sysTask = sysTaskService.getSysTaskById(sysTaskPlan.getTaskId());
            ValidatorBean.checkNotNull(sysTask,"任务不存在");

            // 设置冗余信息
            sysTaskPlan.setTaskNameRdd(sysTask.getName());
            sysTaskPlan.setTaskSoftTypeRdd(sysTask.getTaskSoftType());
            sysTaskPlan.setTaskCycleNameRdd(sysTaskCycle.getName());
            sysTaskPlan.setTaskCycleExpsRdd(sysTaskCycle.getTaskCycleExps());
            sysTaskPlan.setTaskCycleStartDateTimeRdd(sysTaskCycle.getTaskCycleStartDatetime());
            sysTaskPlan.setTaskCycleEndDateTimeRdd(sysTaskCycle.getTaskCycleEndDatetime());
            sysTaskPlan.setTaskPlanExecNum(0);
            sysTaskPlan.setTaskPlanStatus(CommonEnumUtil.DATA_STATUS.ENABLE.getValue());

            // 唯一检查
            BaseResultBean baseResultBean = getJobService(sysTaskPlan.getTaskSoftTypeRdd()).checkJobExists(sysTaskPlan.getName(),sysTaskPlan.getGroupName());
            if(baseResultBean.isSuccess()){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                        .setErrorDetail("定时任务已存在")
                        .build();
            }

            // 添加至对应模块调度器中
            baseResultBean = getJobService(sysTaskPlan.getTaskSoftTypeRdd()).addTask(sysTask.getTaskPackage(),
                    sysTask.getTaskClass(),sysTaskPlan.getName(),sysTaskPlan.getGroupName(),sysTaskCycle.getTaskCycleExps(),
                    sysTaskPlan.getTaskPlanDescription());
            if (!baseResultBean.isSuccess()) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                        .setErrorDetail("定时任务添加失败")
                        .build();
            }

            sysTaskPlan  = sysTaskPlanService.insertSysTaskPlan(sysTaskPlan);

            // 立即执行
            if(isExecute != null && isExecute){
                baseResultBean = getJobService(sysTaskPlan.getTaskSoftTypeRdd()).executeJob(sysTaskPlan.getName(),sysTaskPlan.getGroupName());
                if (!baseResultBean.isSuccess()) {
                    throw ImppExceptionBuilder.newInstance()
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                            .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                            .setErrorDetail("定时任务执行失败")
                            .build();
                }
            }
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(sysTaskPlan);
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping(value = "/update")
    @ApiOperation(value = "修改任务计划", notes = "任务计划")
    public ResultBean updateSysTaskTime(SysTaskPlan sysTaskPlan, Boolean isExecute) {
        try {
            // 数据校验
            ValidatorBean.beginValid(sysTaskPlan)
                    .notNull("name", sysTaskPlan.getName())
                    .notNull("groupName",sysTaskPlan.getGroupName())
                    .notNull("taskCycleId",sysTaskPlan.getTaskCycleId())
                    .notNull("taskId",sysTaskPlan.getTaskId())
                    .notNull("taskMethodType", sysTaskPlan.getTaskMethodType());

            SysTaskCycle sysTaskCycle = sysTaskCycleService.getSysTaskCycleById(sysTaskPlan.getTaskCycleId());
            ValidatorBean.checkNotNull(sysTaskCycle,"任务周期不存在");

            SysTask sysTask = sysTaskService.getSysTaskById(sysTaskPlan.getTaskId());
            ValidatorBean.checkNotNull(sysTask,"任务不存在");

            sysTaskPlan.setTaskNameRdd(sysTask.getName());
            sysTaskPlan.setTaskSoftTypeRdd(sysTask.getTaskSoftType());
            sysTaskPlan.setTaskCycleNameRdd(sysTaskCycle.getName());
            sysTaskPlan.setTaskCycleExpsRdd(sysTaskCycle.getTaskCycleExps());
            sysTaskPlan.setTaskCycleStartDateTimeRdd(sysTaskCycle.getTaskCycleStartDatetime());
            sysTaskPlan.setTaskCycleEndDateTimeRdd(sysTaskCycle.getTaskCycleEndDatetime());

            sysTaskPlanService.updateSysTaskPlan(sysTaskPlan);

            // 修改对应模块中的定时任务
            getJobService(sysTaskPlan.getTaskSoftTypeRdd()).editTask(sysTask.getTaskPackage(),sysTask.getTaskClass(),sysTaskPlan.getName()
                    ,sysTaskPlan.getGroupName(),sysTaskCycle.getTaskCycleExps(),sysTaskPlan.getTaskPlanDescription());

            if(isExecute != null && isExecute){
                getJobService(sysTaskPlan.getTaskSoftTypeRdd()).executeJob(sysTaskPlan.getName(),sysTaskPlan.getGroupName());
            }
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(sysTaskPlan);
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @DeleteMapping(value = "/delete/{id}")
    @ApiOperation(value = "删除任务计划", notes = "删除任务计划")
    public ResultBean deleteSysTaskTime(@PathVariable("id") String id) {
        try {
            // 数据校验
            ValidatorBean.checkNotNull(id, "任务计划id 不能为空");
            SysTaskPlan sysTaskPlan = sysTaskPlanService.getSysTaskPlanById(Long.parseLong(id));
            ValidatorBean.checkNotNull(sysTaskPlan, "定时任务计划不存在");

            sysTaskPlanService.deleteSysTaskPlanById(Long.parseLong(id));
            getJobService(sysTaskPlan.getTaskSoftTypeRdd()).deleteTask(sysTaskPlan.getName(),sysTaskPlan.getGroupName());

            return ResultBean.success().setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value = "/list")
    @ApiOperation(value = "查询SysTaskTime", notes = "查询所有任务计划")
    public ResultBean findSysTaskTimeAll() {
        try {
            List<SysTaskPlan> list = sysTaskPlanService.listSysTaskPlan();
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultList(list);
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value = "/get/{id}")
    @ApiOperation(value = "查询任务计划", notes = "查询根据ID查询任务计划")
    public ResultBean getBySysTaskTimeId(@PathVariable("id") String id) {
        try {
            // 数据校验
            ValidatorBean.checkNotNull(id, "任务计划id 不能为空");

            SysTaskPlan sysTaskPlan = sysTaskPlanService.getSysTaskPlanById(Long.parseLong(id));
            ValidatorBean.checkNotNull(sysTaskPlan, "定时任务计划不存在");

            return ResultBean.success("操作成功").setResultObject(sysTaskPlan).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping(value = "/status/{id}/{status}")
    @ApiOperation(value = "修改任务计划状态", notes = "根据ID修改任务计划状态")
    public ResultBean updateQuartzStatus(@PathVariable("id") String idStr,@PathVariable("status") Integer status) {
        try {
            // 数据校验
            ValidatorBean.checkNotNull(idStr, "id 不能为空");
            ValidatorBean.checkNotZero(status, "状态不能为空");

            SysTaskPlan sysTaskPlan = sysTaskPlanService.getSysTaskPlanById(Long.parseLong(idStr));
            ValidatorBean.checkNotNull(sysTaskPlan, "定时任务计划不存在");

            sysTaskPlanService.updateSysTaskPlanStatus(Long.parseLong(idStr),status,AuthUtil.getSessionUser());

            // 停止或启用对应模块中的定时任务
            if(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == status.intValue()){
                getJobService(sysTaskPlan.getTaskSoftTypeRdd()).pauseJob(sysTaskPlan.getName(),sysTaskPlan.getGroupName());
            }else if(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() == status.intValue()){
                getJobService(sysTaskPlan.getTaskSoftTypeRdd()).resumeJob(sysTaskPlan.getName(),sysTaskPlan.getGroupName());
            }
            return new ResultBean(true);
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping("/query")
    @ApiOperation(value = "任务计划复杂查询，分页，排序",notes = "任务计划复杂查询，分页，排序")
    public ResultBean querySysTaskTimeByPager(SysTaskPlan taskTime, Pager pager){
        try {
            ListPager taskTimeListPager = sysTaskPlanService.querySysTaskPlanByPager(taskTime,pager);
            return  ResultBean.success("操作成功").setListPager(taskTimeListPager).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value = "/execute/{id}")
    @ApiOperation(value = "立即执行", notes = "立即执行")
    public ResultBean executeBySysTaskTimeId(@PathVariable("id") String id) {
        try {
            // 数据校验
            ValidatorBean.checkNotNull(id, "任务计划id 不能为空");
            SysTaskPlan sysTaskPlan = sysTaskPlanService.getSysTaskPlanById(Long.parseLong(id));

            // 执行定时任务
            getJobService(sysTaskPlan.getTaskSoftTypeRdd()).executeJob(sysTaskPlan.getName(),sysTaskPlan.getGroupName());

            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }
}