package com.yunzhupaas.integrate.job;

import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.database.util.TenantDataSourceUtil;
import com.yunzhupaas.exception.TenantInvalidException;
import com.yunzhupaas.integrate.entity.IntegrateEntity;
import com.yunzhupaas.integrate.entity.IntegrateQueueEntity;
import com.yunzhupaas.integrate.model.nodeJson.IntegrateModel;
import com.yunzhupaas.integrate.service.IntegrateQueueService;
import com.yunzhupaas.integrate.service.IntegrateService;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.RandomUtil;
import com.yunzhupaas.util.RedisUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.context.SpringContext;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Date;
import java.util.Objects;


@Slf4j
@DisallowConcurrentExecution
public class Integrate extends QuartzJobBean {


    private static RedisUtil redisUtil;
    private static ConfigValueUtil configValueUtil;
    private static IntegrateService integrateService;
    private static IntegrateQueueService integrateQueueService;

    static {
        redisUtil = SpringContext.getBean(RedisUtil.class);
        configValueUtil = SpringContext.getBean(ConfigValueUtil.class);
        integrateService = SpringContext.getBean(IntegrateService.class);
        integrateQueueService = SpringContext.getBean(IntegrateQueueService.class);
    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        JobDetail jobDetail = context.getJobDetail();
        String jobName = jobDetail.getKey().getName();
        JobDataMap jobDataMap = jobDetail.getJobDataMap();
        IntegrateModel model = IntegrateJobUtil.getModel(JsonUtil.getJsonToBean(jobDataMap, IntegrateModel.class), redisUtil);
        boolean isModel = model == null;
        IntegrateModel integrateModel = isModel ? JsonUtil.getJsonToBean(jobDataMap, IntegrateModel.class) : model;
        if (integrateModel != null) {
            UserInfo userInfo = integrateModel.getUserInfo();
            if (configValueUtil.isMultiTenancy()) {
                try {
                    TenantDataSourceUtil.switchTenant(userInfo.getTenantId());
                }catch (TenantInvalidException e){
                    // 租户无效 禁用调度, 删除任务
                    log.error("Integrate, 租户无效, 删除任务：{}", userInfo.getTenantId());
                    IntegrateJobUtil.removeModel(integrateModel, redisUtil);
                    QuartzUtil.deleteJob(jobName);
                    return;
                }
            }
            IntegrateEntity info = integrateService.getInfo(integrateModel.getId());
            if (info != null) {
                integrateModel.setTime(System.currentTimeMillis());
                Integer num = integrateModel.getNum();
                Integer endTimeType = integrateModel.getEndTimeType();
                Integer endLimit = integrateModel.getEndLimit();
                boolean isNext = Objects.equals(endTimeType, 1) ? num + 1 <= endLimit : Objects.equals(endTimeType, 2) ? integrateModel.getTime() <= integrateModel.getEndTime() : true;
                integrateModel.setNum(++num);
                if (isNext) {
                    IntegrateJobUtil.insertModel(integrateModel, redisUtil);
                    IntegrateQueueEntity entity = new IntegrateQueueEntity();
                    entity.setState(0);
                    entity.setId(RandomUtil.uuId());
                    entity.setIntegrateId(integrateModel.getId());
                    entity.setExecutionTime(new Date());
                    entity.setFullName(info.getFullName());
                    IntegrateModel integrate  = new IntegrateModel();
                    integrate.setId(entity.getId());
                    integrate.setUserInfo(userInfo);
                    IntegrateJobUtil.insertIntegrate(integrate,redisUtil);
                    integrateQueueService.create(entity);
                } else {
                    IntegrateJobUtil.removeModel(integrateModel, redisUtil);
                    QuartzUtil.deleteJob(jobName);
                }
            } else {
                IntegrateJobUtil.removeModel(integrateModel, redisUtil);
                QuartzUtil.deleteJob(jobName);
            }
        }
    }


}

