package com.inspect.job.controller;

import com.inspect.base.core.constant.Constants;
import com.inspect.base.core.exception.job.TaskException;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.core.utils.poi.ExcelUtil;
import com.inspect.base.core.web.controller.BaseController;
import com.inspect.base.core.web.domain.AjaxResult;
import com.inspect.base.core.web.page.TableDataInfo;
import com.inspect.common.log.annotation.Log;
import com.inspect.common.log.enums.BizType;
import com.inspect.common.security.annotation.RequiresPermissions;
import com.inspect.common.security.utils.SecurityUtils;
import com.inspect.job.domain.SysJob;
import com.inspect.job.service.ISysJobService;
import com.inspect.job.util.CronUtils;
import com.inspect.job.util.ScheduleUtils;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping({"/job"})
public class SysJobController extends BaseController {
   @Autowired
   private ISysJobService jobService;

   @RequiresPermissions({"monitor:job:list"})
   @GetMapping({"/list"})
   public TableDataInfo list(SysJob sysJob) {
      this.startPage();
      List<SysJob> list = this.jobService.selectJobList(sysJob);
      return this.getDataTable(list);
   }

   @RequiresPermissions({"monitor:job:export"})
   @Log(
      title = "定时任务",
      businessType = BizType.EXPORT
   )
   @PostMapping({"/export"})
   public void export(HttpServletResponse response, SysJob sysJob) {
      List<SysJob> list = this.jobService.selectJobList(sysJob);
      ExcelUtil<SysJob> util = new ExcelUtil(SysJob.class);
      util.exportExcel(response, list, "定时任务");
   }

   @RequiresPermissions({"monitor:job:query"})
   @GetMapping({"/{jobId}"})
   public AjaxResult getInfo(@PathVariable("jobId") Long jobId) {
      return AjaxResult.success(this.jobService.selectJobById(jobId));
   }

   @RequiresPermissions({"monitor:job:add"})
   @Log(
      title = "定时任务",
      businessType = BizType.INSERT
   )
   @PostMapping
   public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException {
      if(!CronUtils.isValid(job.getCronExpression())) {
         return this.error("新增任务'" + job.getJobName() + "'失败，Cron表达式不正确");
      } else if(StringUtils.containsIgnoreCase(job.getInvokeTarget(), "rmi:")) {
         return this.error("新增任务'" + job.getJobName() + "'失败，目标字符串不允许'rmi'调用");
      } else if(StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[]{"ldap:", "ldaps:"})) {
         return this.error("新增任务'" + job.getJobName() + "'失败，目标字符串不允许'ldap(s)'调用");
      } else if(StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[]{"http://", "https://"})) {
         return this.error("新增任务'" + job.getJobName() + "'失败，目标字符串不允许'http(s)'调用");
      } else if(StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) {
         return this.error("新增任务'" + job.getJobName() + "'失败，目标字符串存在违规");
      } else if(!ScheduleUtils.whiteList(job.getInvokeTarget())) {
         return this.error("新增任务'" + job.getJobName() + "'失败，目标字符串不在白名单内");
      } else {
         job.setCreateBy(SecurityUtils.getUsername());
         return this.toAjax(this.jobService.insertJob(job));
      }
   }

   @RequiresPermissions({"monitor:job:edit"})
   @Log(
      title = "定时任务",
      businessType = BizType.UPDATE
   )
   @PostMapping({"/edit"})
   public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException {
      if(!CronUtils.isValid(job.getCronExpression())) {
         return this.error("修改任务'" + job.getJobName() + "'失败，Cron表达式不正确");
      } else if(StringUtils.containsIgnoreCase(job.getInvokeTarget(), "rmi:")) {
         return this.error("修改任务'" + job.getJobName() + "'失败，目标字符串不允许'rmi'调用");
      } else if(StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[]{"ldap:", "ldaps:"})) {
         return this.error("修改任务'" + job.getJobName() + "'失败，目标字符串不允许'ldap(s)'调用");
      } else if(StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[]{"http://", "https://"})) {
         return this.error("修改任务'" + job.getJobName() + "'失败，目标字符串不允许'http(s)'调用");
      } else if(StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) {
         return this.error("修改任务'" + job.getJobName() + "'失败，目标字符串存在违规");
      } else if(!ScheduleUtils.whiteList(job.getInvokeTarget())) {
         return this.error("修改任务'" + job.getJobName() + "'失败，目标字符串不在白名单内");
      } else {
         job.setUpdateBy(SecurityUtils.getUsername());
         return this.toAjax(this.jobService.updateJob(job));
      }
   }

   @RequiresPermissions({"monitor:job:changeStatus"})
   @Log(
      title = "定时任务",
      businessType = BizType.UPDATE
   )
   @PostMapping({"/changeStatus"})
   public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException {
      SysJob newJob = this.jobService.selectJobById(job.getJobId());
      newJob.setStatus(job.getStatus());
      return this.toAjax(this.jobService.changeStatus(newJob));
   }

   @RequiresPermissions({"monitor:job:changeStatus"})
   @Log(
      title = "定时任务",
      businessType = BizType.UPDATE
   )
   @PostMapping({"/run"})
   public AjaxResult run(@RequestBody SysJob job) throws SchedulerException {
      this.jobService.run(job);
      return AjaxResult.success();
   }

   @RequiresPermissions({"monitor:job:remove"})
   @Log(
      title = "定时任务",
      businessType = BizType.DELETE
   )
   @PostMapping({"/remove/{jobIds}"})
   public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException {
      this.jobService.deleteJobByIds(jobIds);
      return AjaxResult.success();
   }
}
