package org.wcs.business.http;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.wcs.business.data.intf.IDataRecorder;
import org.wcs.constant.ConstantData;
import org.wcs.plugin.webHttpClient.intef.IHttpRequestEvent;
import org.wcs.plugin.webHttpClient.model.HttpRequest;
import org.wcs.plugin.webHttpClient.model.HttpResponse;
import org.wcs.utils.AppStringUtils;
import org.wcs.utils.AppUUIDUtils;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service("HttpRequestRecord")
@RequiredArgsConstructor
public class HttpRequestRecord implements IHttpRequestEvent {

    private final IDataRecorder dataRecorder; // 数据记录类
    private final StringRedisTemplate redisTemplate; // redis字符串操作类


    private static final String HTTP_REQUEST_CACHE = ConstantData.SYSTEM_NAME + ":HTTP:REQUEST";

    /**
     * 请求开始之前
     * @param request 请求对象
     */
    @Override
    public void beforeRequest(HttpRequest request) {

    }

    /**
     * 请求结束之后
     * @param request 请求对象
     * @param response 响应对象
     */
    @Override
    public void afterRequest(HttpRequest request, HttpResponse response) {
        log.info("WCS对外请求，请求数据：{}；响应数据：{}", request, response);
        dataRecorder.recordApiRequestData(response);
        String redisKey = HTTP_REQUEST_CACHE + ":" + request.getId();
        if(request.isAutoRetry() && !response.isBaseDataError() && !response.isSuccess()) {
            // 请求失败了
            int retryCount = request.getRetryCount();
            if(retryCount >= 5000) {
                return;
            }
            request.setRetryCount(retryCount + 1);
            LocalDateTime nextRetryTime = request.getNextRetryTime();
            if(nextRetryTime == null) {
                request.setNextRetryTime(LocalDateTime.now().plusSeconds(5));
            } else {
                int addRatio = Math.min(retryCount, 10);
                request.setNextRetryTime(nextRetryTime.plusSeconds(addRatio * 5L));
            }
            request.setNextRetryTime(nextRetryTime);
            if(AppStringUtils.isEmpty(request.getId())) {
                request.setId(AppUUIDUtils.getNewUUID());
            }
            Long expireTime = redisTemplate.opsForValue().getOperations().getExpire(redisKey, TimeUnit.MINUTES); // 获取过期时间
            if(expireTime != null && expireTime == -2 && request.getRetryCount() > 1) {
                return; // 重发过，但是已经过期了，不再重发，防止重发定时任务刚重发就过期，这边再次添加缓存，导致不间断发送
            }
            expireTime = expireTime == null || expireTime < 0 || request.getRetryCount() == 0 ? 180 : expireTime;
            redisTemplate.opsForValue().set(redisKey, AppStringUtils.objectToString(request), expireTime, TimeUnit.MINUTES); // 设置过期时间
        } else {
            redisTemplate.delete(redisKey);
        }

    }
}
