package com.zjty.tynotes.log.base.aspect;

import com.zjty.tynotes.log.dao.LogDao;
import com.zjty.tynotes.log.entity.Log;
import com.zjty.tynotes.pas.base.advise.Content;
import com.zjty.tynotes.pas.base.advise.ContentParse;
import com.zjty.tynotes.pas.dao.PasUserDao;
import com.zjty.tynotes.pas.entity.User;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @Author gwj
 * @create 2020/4/23 8:57
 */
@Aspect
@Component
@Slf4j
public class ControllerAspect {
    @Autowired
    private PasUserDao pasUserDao;
    @Autowired
    private LogDao logDao;

    private final static Logger logger = LoggerFactory.getLogger(ControllerAspect.class);

    /**
     * 定义切点
     */
    @Pointcut("execution(public * com.zjty.tynotes.pas.controller.*.*(..))")
    public void privilege1(){}

//    @Pointcut("execution(public * com.zjty.tynotes.job.basic.controller.*.*(..))")
//    public void privilege2(){}

    @Pointcut("execution(public * com.zjty.tynotes.attendance.controller.*.*(..))")
    public void privilege3(){}

    @Pointcut("execution(public * com.zjty.tynotes.pas.config.handler.MySuccessHandler.onAuthenticationSuccess(..))")
    public void privilege4(){}

//    @Pointcut("execution(public * com.zjty.tynotes.weekly.subject.controller.*.*(..))")
//    public void privilege4(){}

    /**
     * 日志记录的环绕通知
     * @param joinPoint
     * @throws Throwable
     */
    @Around("privilege1() || privilege3()||privilege4()")
    public Object isLogMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            // 接收到请求，记录请求内容
            //获取访问目标方法
            MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
            Method targetMethod = methodSignature.getMethod();
            //得到方法的功能描述，生成日志信息
            final Content content = ContentParse.privilegeParse(targetMethod);
            //得到方法的访问权限
            // final String[] methodAccess = AccessAnnotationParse.privilegeParse(targetMethod);
            if(content!=null){
                String contentValue = content.value();
                User user = null;
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (authentication != null) {
                    if (authentication instanceof AnonymousAuthenticationToken) {
                        return null;
                    }

                    if (authentication instanceof UsernamePasswordAuthenticationToken) {
                        user = (User) authentication.getPrincipal();
                    }
                }


                if(authentication!=null){
                    String username = user.getUsername();
                    String description = username + "执行" + contentValue;
                    logger.info(description);
                    Log log = new Log(null,description,new Date(),null,username);
                    User byUsername = pasUserDao.findByUsername(username);
                    if(byUsername!=null){
                        log.setUserId(byUsername.getId());
                    }
                    logDao.save(log);
                    Object proceed = joinPoint.proceed();
                    return proceed;
                }
            }

            Object proceed = joinPoint.proceed();
            return proceed;
        }catch (Exception e){
            Object proceed = joinPoint.proceed();
            e.printStackTrace();
            logger.error("aop日志记录出现异常:{}",e.getMessage());
            return proceed;
        }
    }
}
