package com.jwipc.job.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.jwipc.job.logic.JobServiceLogic;
import com.jwipc.job.prop.JobProp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * <p> </p>
 *
 * @author ZhangJie
 * @version 1.0
 * @since JDK 1.8
 */
@RestController
@RequestMapping("/job")
@RequiredArgsConstructor
@Slf4j
public class JobController {
    @Autowired
    @Lazy
    private JobServiceLogic jobService;
    @Autowired
    private JobProp jobProp;

    @PostMapping("schedule")
    public ResponseEntity schedule(
            @RequestParam("jobName") String jobName,
            @RequestParam("jobClass") String jobClassName,
            @RequestParam("scheduleTime") String jobScheduleTime,
            @RequestParam("cronEx") String cronExpression,
            @RequestParam("remark") String remark
    )
    {

        //Job Name is mandatory
        if (jobName == null || StrUtil.isEmpty(jobName)) {
            return ResponseEntity.badRequest().body("任务名称不能为空");
        }

        final Class<?> jobClass;
        jobClassName = jobProp.basePackage + StrUtil.DOT + jobClassName;
        try {
            jobClass = Class.forName(jobClassName);
        } catch (ClassNotFoundException e) {
            return ResponseEntity.badRequest().body("执行器类未找到");
        }
        //Check if job Name is unique;
        if (!jobService.isJobWithNamePresent(jobName)) {

            final DateTime dateTime = DateUtil.parse(jobScheduleTime, "yyyy-MM-dd HH:mm");
            //Cron Trigger
            boolean status1 = jobService.scheduleCronJob(jobName, (Class<? extends QuartzJobBean>) jobClass, dateTime,
                    cronExpression, remark);
            if (status1) {

                return ResponseEntity.ok(StrUtil.EMPTY);
            } else {
                return ResponseEntity.badRequest().body("添加失败");
            }
        }
        return ResponseEntity.badRequest().body("任务名重复");
    }

    @PostMapping("unschedule")
    public void unschedule(@RequestParam("jobName") String jobName) {
        jobService.unScheduleJob(jobName);
    }

    @PostMapping("delete")
    public ResponseEntity delete(@RequestParam("jobName") String jobName) {

        if (jobService.isJobWithNamePresent(jobName)) {
            boolean isJobRunning = jobService.isJobRunning(jobName);

            if (!isJobRunning) {
                boolean status = jobService.deleteJob(jobName);
                if (status) {
                    return ResponseEntity.ok(StrUtil.EMPTY);
                } else {
                    return ResponseEntity.badRequest().body("删除失败");
                }
            } else {
                return ResponseEntity.badRequest().body("任务正在运行无法删除");
            }
        } else {
            //Job doesn't exist

            return ResponseEntity.badRequest().body("定时任务不存在");
        }
    }

    @PostMapping("pause")
    public ResponseEntity pause(@RequestParam("jobName") String jobName) {

        if (jobService.isJobWithNamePresent(jobName)) {

            boolean isJobRunning = jobService.isJobRunning(jobName);

            if (!isJobRunning) {
                boolean status = jobService.pauseJob(jobName);
                if (status) {
                    return ResponseEntity.ok(StrUtil.EMPTY);
                } else {
                    return ResponseEntity.badRequest().body("任务暂停失败");
                }
            } else {
                return ResponseEntity.badRequest().body("任务正在运行无法暂停");
            }

        } else {
            //Job doesn't exist
            return ResponseEntity.badRequest().body("定时任务不存在");
        }
    }

    @PostMapping("resume")
    public ResponseEntity resume(@RequestParam("jobName") String jobName) {

        if (jobService.isJobWithNamePresent(jobName)) {
            String jobState = jobService.getJobState(jobName);

            final boolean paused = StrUtil.equals("PAUSED", jobState);
            if (paused) {
                boolean status = jobService.resumeJob(jobName);

                if (status) {
                    return ResponseEntity.ok(StrUtil.EMPTY);
                } else {
                    return ResponseEntity.badRequest().body("任务启用失败");
                }
            } else {
                return ResponseEntity.badRequest().body("任务不是禁用状态");
            }

        } else {
            //Job doesn't exist
            return ResponseEntity.badRequest().body("定时任务不存在");
        }
    }

    @PostMapping("update")
    public ResponseEntity updateJob(
            @RequestParam("jobName") String jobName,
            @RequestParam("scheduleTime") String jobScheduleTime,
            @RequestParam("cronEx") String cronExpression,
            @RequestParam("remark") String remark
    )
    {

        //Job Name is mandatory
        if (StrUtil.isEmpty(jobName)) {
            return ResponseEntity.badRequest().body("任务名称不能为空");
        }
        //Edit Job
        if (jobService.isJobWithNamePresent(jobName)) {
            if (StrUtil.isEmpty(cronExpression)) {
                //Single Trigger
                boolean status = jobService.updateOneTimeJob(jobName,
                        DateUtil.parse(jobScheduleTime, "yyyy-MM-dd HH:mm"), remark);
                if (status) {
                    return ResponseEntity.ok().build();
                } else {
                    return ResponseEntity.badRequest().body("任务更新失败");
                }

            } else {
                //Cron Trigger
                boolean status = jobService.updateCronJob(jobName, DateUtil.parse(jobScheduleTime, "yyyy-MM-dd HH:mm"),
                        cronExpression, remark);
                if (status) {
                    return ResponseEntity.ok().build();
                } else {
                    return ResponseEntity.badRequest().body("任务更新失败");
                }
            }

        } else {
            return ResponseEntity.badRequest().body("定时任务不存在");
        }
    }

    @GetMapping("jobs")
    public ResponseEntity getAllJobs() {
        List<Map<String, String>> list = jobService.getAllJobs();
        return ResponseEntity.ok(list);
    }

    @GetMapping("job")
    public ResponseEntity getJob(@RequestParam("jobName") String jobName) {
        //Job Name is mandatory
        if (StrUtil.isEmpty(jobName)) {
            return ResponseEntity.badRequest().body("任务名称不能为空");
        }
        List<Map<String, String>> list = jobService.getAllJobs();
        for (Map<String, String> stringObjectMap : list) {
            final String name = stringObjectMap.get("jobName");
            if (jobName.equals(name)) {
                return ResponseEntity.ok(stringObjectMap);
            }
        }
        return ResponseEntity.ok(list);
    }

    @PostMapping("stop")
    public ResponseEntity stopJob(@RequestParam("jobName") String jobName) {

        if (jobService.isJobWithNamePresent(jobName)) {

            if (jobService.isJobRunning(jobName)) {
                boolean status = jobService.stopJob(jobName);
                if (status) {
                    return ResponseEntity.ok(StrUtil.EMPTY);
                } else {
                    //Server error
                    return ResponseEntity.badRequest().body("停止任务失败");
                }

            } else {
                //Job not in running state
                return ResponseEntity.badRequest().body("任务没有运行");
            }

        } else {
            //Job doesn't exist

            return ResponseEntity.badRequest().body("定时任务不存在");
        }
    }

    @PostMapping("start")
    public ResponseEntity startJobNow(@RequestParam("jobName") String jobName) {

        if (jobService.isJobWithNamePresent(jobName)) {

            if (!jobService.isJobRunning(jobName)) {
                boolean status = jobService.startJobNow(jobName);

                if (status) {
                    //Success
                    return ResponseEntity.ok(StrUtil.EMPTY);
                } else {
                    //Server error
                    return ResponseEntity.badRequest().body("运行任务失败");
                }
            } else {
                //Job already running
                return ResponseEntity.badRequest().body("任务正在运行");
            }
        } else {
            //Job doesn't exist
            return ResponseEntity.badRequest().body("定时任务不存在");
        }
    }


}
