content: package com.aizuda.snailjob.server.retry.task.support.handler;
  
  import cn.hutool.core.lang.Assert;
  import cn.hutool.core.util.StrUtil;
  import com.aizuda.snailjob.common.core.enums.RetryStatusEnum;
  import com.aizuda.snailjob.common.core.enums.StatusEnum;
  import com.aizuda.snailjob.common.core.util.JsonUtil;
  import com.aizuda.snailjob.server.common.WaitStrategy;
  import com.aizuda.snailjob.server.common.config.SystemProperties;
  import com.aizuda.snailjob.server.common.enums.SyetemTaskTypeEnum;
  import com.aizuda.snailjob.server.common.exception.SnailJobServerException;
  import com.aizuda.snailjob.server.common.strategy.WaitStrategies.WaitStrategyContext;
  import com.aizuda.snailjob.server.common.strategy.WaitStrategies.WaitStrategyEnum;
  import com.aizuda.snailjob.server.common.util.DateUtils;
  import com.aizuda.snailjob.server.retry.task.support.RetryTaskConverter;
  import com.aizuda.snailjob.server.retry.task.support.RetryTaskLogConverter;
  import com.aizuda.snailjob.template.datasource.access.AccessTemplate;
  import com.aizuda.snailjob.template.datasource.persistence.mapper.RetryTaskMapper;
  import com.aizuda.snailjob.template.datasource.persistence.po.Retry;
  import com.aizuda.snailjob.template.datasource.persistence.po.RetrySceneConfig;
  import com.aizuda.snailjob.template.datasource.persistence.po.RetryTask;
  import lombok.RequiredArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
  import org.slf4j.helpers.FormattingTuple;
  import org.slf4j.helpers.MessageFormatter;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.dao.DuplicateKeyException;
  import org.springframework.stereotype.Component;
  import org.springframework.transaction.annotation.Transactional;
  
  import java.time.LocalDateTime;
  import java.util.Objects;
  
  
  /**
   * 回调数据处理器
   *
   * @author opensnail
   * @date 2023-06-04
   * @since 1.5.0
   */
  @Component
  @Slf4j
  @RequiredArgsConstructor
  public class CallbackRetryTaskHandler {
      private final AccessTemplate accessTemplate;
  
      /**
       * 创建回调数据
       *
       * @param parentRetry            {@link Retry} 重试任务数据
       * @param retrySceneConfig
       */
      public void create(Retry parentRetry, RetrySceneConfig retrySceneConfig) {
          if (!SyetemTaskTypeEnum.RETRY.getType().equals(parentRetry.getTaskType())) {
              return;
          }
  
          if (Objects.isNull(retrySceneConfig.getCbStatus()) ||
                  StatusEnum.NO.getStatus().equals(retrySceneConfig.getCbStatus())) {
              return;
          }
  
          Retry callbackRetry = RetryTaskConverter.INSTANCE.toRetryTask(parentRetry);
          callbackRetry.setTaskType(SyetemTaskTypeEnum.CALLBACK.getType());
          callbackRetry.setParentId(parentRetry.getId());
          callbackRetry.setRetryStatus(RetryStatusEnum.RUNNING.getStatus());
          callbackRetry.setRetryCount(0);
          callbackRetry.setCreateDt(LocalDateTime.now());
          callbackRetry.setUpdateDt(LocalDateTime.now());
  
          String triggerInterval = retrySceneConfig.getCbTriggerInterval();
          WaitStrategy waitStrategy = WaitStrategyEnum.getWaitStrategy(retrySceneConfig.getCbTriggerType());
          WaitStrategyContext waitStrategyContext = new WaitStrategyContext();
          waitStrategyContext.setNextTriggerAt(DateUtils.toNowMilli());
          waitStrategyContext.setDelayLevel(1);
          waitStrategyContext.setTriggerInterval(String.valueOf(triggerInterval));
  
          callbackRetry.setNextTriggerAt(waitStrategy.computeTriggerTime(waitStrategyContext));
  
          try {
              Assert.isTrue(1 == accessTemplate.getRetryAccess().insert(callbackRetry),
                      () -> new SnailJobServerException("failed to report data"));
          } catch (DuplicateKeyException e) {
              log.warn("Callback data duplicate insertion. [{}]", JsonUtil.toJsonString(callbackRetry));
          }
      }
  
  //    /**
  //     * 生成回调数据
  //     *
  //     * @param uniqueId 重试任务uniqueId
  //     * @return 回调任务uniqueId
  //     */
  //    public String generatorCallbackUniqueId(String uniqueId) {
  //        // eg: CB_202307180949471
  //        FormattingTuple callbackUniqueId = MessageFormatter.arrayFormat(CALLBACK_UNIQUE_ID_RULE,
  //                new Object[]{systemProperties.getCallback().getPrefix(), uniqueId});
  //
  //        return callbackUniqueId.getMessage();
  //    }
  
      /**
       * 获取重试任务uniqueId
       *
       * @param callbackTaskUniqueId 回调任务uniqueId
       * @return 重试任务uniqueId
       */
      public String getRetryTaskUniqueId(String callbackTaskUniqueId) {
          return callbackTaskUniqueId.substring(callbackTaskUniqueId.lastIndexOf(StrUtil.UNDERLINE) + 1);
      }
  
  }
  