package com.reyun.saas.mob.user.task;

import com.reyun.saas.common.constants.WorkOrderExportEnum;
import com.reyun.saas.common.util.RedisUtils;
import com.reyun.saas.mob.user.dao.WorkOrderMapper;
import com.reyun.saas.mob.user.domain.WorkOrderExport;
import com.reyun.saas.mob.user.thread.workorder.WorkOrderThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 扫描订单创建任务
 */
@Slf4j
@Component
public class WorkOrderTask {

    /**
     * 两小时
     */
    private static final Long twoHour = 2000L * 60L * 60L;

    @Resource
    private WorkOrderMapper workOrderMapper;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private ThreadPoolExecutor workOrderThreadPool;

    @Async
//    @Scheduled(cron = "0 0/5 * * * ?")
    @Scheduled(cron = "0 * * * * ?")
    public void scanWorkOrderExport() {
        //分布式锁
        if (!redisUtils.tryLock("scanWorkOrderExport",10)) {
            log.info("另一台服务正在创建工单中.......");
            return;
        }

//        log.info("扫描需要导出的日志任务");

        Example example = new Example(WorkOrderExport.class);
        //查询等待导出和整在导出的任务
        example.and().andEqualTo("status", WorkOrderExportEnum.EXPORT_DOWNLOADING.getCode())
                .orEqualTo("status", WorkOrderExportEnum.EXPORT_INIT.getCode());
        example.and().andEqualTo("delFlag", false);


        List<WorkOrderExport> workOrderExports = workOrderMapper.selectByExample(example);
        if (workOrderExports != null) {
            for (WorkOrderExport workOrderExport : workOrderExports) {
                //如果状态是正在导出  并且离创建时间过去了2小时  判定为任务异常终止 将它状态改为创建失败
                if(WorkOrderExportEnum.EXPORT_DOWNLOADING.getCode().equals(workOrderExport.getStatus())){
                    Long time = workOrderExport.getCreateDate().getTime() + twoHour;
                    if (time < System.currentTimeMillis()) {
                        workOrderExport.setStatus(WorkOrderExportEnum.EXPORT_FAILED.getCode());
                        workOrderMapper.updateByPrimaryKeySelective(workOrderExport);
                        log.info("将一个异常终止的导出任务状态改为创建失败 id为{}", workOrderExport.getId());
                        continue;
                    }
                }

                //使用线程池异步处理日志
                try {
                    workOrderThreadPool.execute(new WorkOrderThread(workOrderExport));
                } catch (RejectedExecutionException e) {
                    log.error("workOrder线程池已满 ", e);
                } catch (Exception exception) {
                    log.error("发生未知异常", exception);
                }
            }
        }
    }


    /**
     * 将工期的工单删除
     */
    @Async
    @Scheduled(cron = "0 0 * * * ?")
    public void expireWorkOrderDispose() {

        //分布式锁
        if (!redisUtils.tryLock("expireWorkOrderDispose",10)) {
            log.info("另一台服务正在处理过期的工单中中.......");
            return;
        }

        log.info("扫描文件过期的工单");

        //获取上个月的时间
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月
        date = calendar.getTime();

        AtomicInteger atomicInteger = new AtomicInteger();
        //扫描订单完成时间早于一个月前的
        Example example = new Example(WorkOrderExport.class);
        example.and().andLessThan("finishDate",date);
        List<WorkOrderExport> workOrderExports = workOrderMapper.selectByExample(example);
        for (WorkOrderExport workOrderExport : workOrderExports) {

            workOrderExport.setDelFlag(true);
            workOrderExport.setStatus(WorkOrderExportEnum.EXPORT_FILE_PAST.getCode());
            workOrderExport.setMsg(WorkOrderExportEnum.EXPORT_FILE_PAST.getName());
            workOrderMapper.updateByPrimaryKeySelective(workOrderExport);
            atomicInteger.incrementAndGet();
            log.info("工单过期  appkey:{} 工单生成时间:{} 创建人:{} 工单id:{} 工单名称:{}",workOrderExport.getAppkey(),workOrderExport.getFinishDate(),
                    workOrderExport.getCreateUser(),workOrderExport.getId(),workOrderExport.getWorkOrderName());
        }

        log.info("删除了{}个过期工单",atomicInteger.get());



    }



}
