package com.dhcc.finance.aop;

import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.dhcc.common.constant.SysConstants;
import com.dhcc.common.constant.SysStatusCode;
import com.dhcc.common.model.CurrencyMeta;
import com.dhcc.common.model.response.RestfulResponse;
import com.dhcc.common.util.Md5Util;
import com.dhcc.common.util.RedisLockHelper;
import com.dhcc.common.util.Resubmit;
import com.dhcc.common.util.SnowflakeIdWorker;
import com.dhcc.finance.util.MetaDataUtil;

import brave.Tracer;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @功能描述：日志及响应状态处理
 * @author chenrui
 * @date 2018年5月23日 上午10:24:03
 * @修改日志：
 */
@Component
@Aspect
@Order(2)
@Slf4j
public class RestfulRequestAspect {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private Tracer tracer;
   
    @Around("@annotation(resubmit)")
    public Object doAround(ProceedingJoinPoint joinPoint, Resubmit resubmit) throws Throwable {
        log.info("系统重复提交："+resubmit.value());
        RedisLockHelper redisLockHelper = new RedisLockHelper(stringRedisTemplate);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String tradeUrl = request.getRequestURI().toString();// 请求地址的资源名部分
        Object[] args = joinPoint.getArgs();// 获得请求参数
        StringBuilder builder = new StringBuilder(tradeUrl);
        for (int i = 0; i < args.length; i++) {
            builder.append(args[i]);
        }
        //生成key
        String key = SysConstants.REDIS_KEY_PREFIX.SYS_CHECK_RESUBMIT + Md5Util.MD5(builder.toString());
        String value = SnowflakeIdWorker.getInstance().nextIdString();
        boolean success = redisLockHelper.lock(key, value, 60, TimeUnit.SECONDS);
        if (!success) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, "请勿重复提交",
                    MetaDataUtil.getMeta(tracer, SysStatusCode.USER_RESUBMIT_ERROR));
        }
        // 执行方法
        Object result = joinPoint.proceed(joinPoint.getArgs());
        //防止死锁,定时执行解锁
        redisLockHelper.unlock(key, value, 60, TimeUnit.SECONDS);
        return result;
    }
}