package com.tzld.piaoquan.ad.engine.server.controller;

import com.google.common.base.Stopwatch;
import com.google.common.collect.Sets;
import com.tzld.piaoquan.ad.engine.commons.util.JSONUtils;
import com.tzld.piaoquan.ad.engine.commons.util.TraceUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author dyp
 */
@Aspect
@Component
@Slf4j
public class ControllerAspect {

    @Pointcut("execution(* com.tzld.piaoquan.ad.engine.server.controller.*Controller.*(..))")
    public void logPointcut() {

    }

    @Pointcut("execution(* com.tzld.piaoquan.ad.engine.server.controller.HealthController.*(..))")
    public void excludePointcut() {

    }

    @Value("${aspect_log_switch:false}")
    private Boolean aspectLogSwitch;

    @Around("logPointcut() && !excludePointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        TraceUtils.setMDC();
        String className = pjp.getTarget().getClass().getSimpleName();
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Stopwatch stopwatch = Stopwatch.createStarted();

        String param = JSONUtils.toJson(pjp.getArgs(), Sets.newHashSet("statisticsLog"));

        if (Boolean.TRUE.equals(aspectLogSwitch)) {
            log.info("request className=[{}], method=[{}], param=[{}]", className, signature.getName(), param);
        }
        Object result = pjp.proceed();
        if (Boolean.TRUE.equals(aspectLogSwitch)) {
            String resultStr = (result instanceof String) ? (String) result : JSONUtils.toJson(result);
            log.info("request method=[{}] param=[{}] result=[{}] cost=[{}]", signature.getName(), param, resultStr, stopwatch.stop().elapsed(TimeUnit.MILLISECONDS));
        }
        TraceUtils.removeMDC();
        return result;
    }


}
