package cn.estsh.i3plus.ext.mes.pcn.apiservice.schedulejob.bu3;

import cn.estsh.i3plus.ext.mes.pcn.api.job.bu3.ISxReworkBindSnService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jboss.logging.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.StringJoiner;
import java.util.concurrent.TimeUnit;

/**
 * @PROJECT_NAME: i3plus-mes-panasonic-bu
 * @DESCRIPTION:
 * @USER: xinwang.yi
 * @DATE: 2022-11-11 11:11
 */
@Slf4j
@DisallowConcurrentExecution
@ApiOperation("下达返工工单关联返工范围条码定时任务")
public class SxReworkOrderBindSnJob implements Job {

    @Autowired
    private ISxReworkBindSnService reworkBindSnService;

    @Resource(name = MesPcnExtConstWords.REDIS_RES_PCN)
    private ImppRedis redisMesPcn;

    private static final Logger LOGGER = Logger.getLogger(SxReworkOrderBindSnJob.class);

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        LOGGER.info(this.getClass().getSimpleName() + " :下达返工工单关联返工范围条码定时任务开始执行...");

        Object param =  jobExecutionContext.getJobDetail().getJobDataMap().get(MesPcnExtConstWords.PARAM);

        if(StringUtils.isEmpty(param)){
            LOGGER.error("Pcn处理下达返工工单关联返工范围条码定时任务开始执行,未配置工厂代码参数");
            return;
        }

        long startTime = System.currentTimeMillis();

        String[] organizeCodeArray = param.toString().split(MesPcnExtConstWords.COMMA);

        for (String organizeCode : organizeCodeArray) {
            String key = new StringJoiner(MesPcnExtConstWords.COLON).add("MES")
                    .add(organizeCode).add("REWORK-ORDER-BIND-SN").toString();
            RLock lock = (RLock) redisMesPcn.getFairLock(key);

            try {
                if (!lock.tryLock(20, 180, TimeUnit.SECONDS)) {
                    log.info("BU-PCN下达状态返工绑定返工条码:尝试锁定JOB:工厂代码[{}]等待超时,超时原因:当前JOB正在执行不能并发操作", organizeCode);
                    continue;
                }
            } catch (Exception e) {
                log.info("BU-PCN下达状态返工绑定返工条码:尝试锁定JOB:工厂代码[{}]等待超时,超时原因:当前JOB正在执行不能并发操作,失败原因:[{}]", organizeCode, e.getMessage());
                continue;
            }

            try {
                reworkBindSnService.doReworkBindSn(organizeCode);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (lock.isLocked() && lock.isHeldByCurrentThread()) lock.unlock();
            }
        }

        long endTime = System.currentTimeMillis();
        LOGGER.info(this.getClass().getSimpleName() + " :ALL:耗时: " + (endTime - startTime) + "ms");
    }
}
