package com.storlead.system.aspect;

import cn.hutool.json.JSONUtil;
import com.storlead.framework.auth.vo.LoginUser;
import com.storlead.framework.util.LoginUserUtil;
import com.storlead.system.enums.OperationLogTypeEnum;
import com.storlead.system.holder.RequestHolder;
import com.storlead.system.pojo.entity.SysOperationLogEntity;
import com.storlead.system.service.SysOperationLogService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
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 javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: sp-sales
 * @description:
 * @author: chenkq
 * @create: 2022-07-29 14:54
 */
@Component
@Aspect
@Slf4j
public class LogAspect {

    ThreadLocal<Long> currentTime = new ThreadLocal<>();

    @Resource
    private SysOperationLogService logService;

    @Value("${server.servlet.context-path}")
    private String requestPrefix;

    /**
     * 配置切入点 利用 Swagger的方法注解
     */
    @Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
    public void logPointCut() {
    }

    /**
     * 配置环绕通知 记录所有操作日志
     *
     * @param joinPoint join point for advice
     * @author blank
     * @date 2021-3-4 上午 10:30
     */
    @Around("logPointCut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        try {
            currentTime.set(System.currentTimeMillis());
            LoginUser currentUser =  LoginUserUtil.getLoginUser();
            result = joinPoint.proceed();
//            SysOperationLogEntity sysLog = new SysOperationLogEntity(OperationLogTypeEnum.INFO, System.currentTimeMillis() - currentTime.get());
//
//            Signature signature = joinPoint.getSignature();
//            MethodSignature methodSignature = (MethodSignature) signature;
//            Method method = methodSignature.getMethod();
//            if (method.isAnnotationPresent(ApiOperation.class)) {
//                ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
//                sysLog.setDescription(apiOperation.value());
//            }
//            sysLog.setResult(JSONUtil.toJsonStr(result));
//
//            HttpServletRequest request = RequestHolder.getHttpServletRequest();
//            //如果还没登陆调用登陆接口得用请求参数中的username
//            String userName = "";
//            if ("upload".equals(signature.getName()) ) {
//                return result;
//            }
//            if (currentUser != null) {
//                userName = currentUser.getRealName();
//            } else {
//                if ("login".equals(signature.getName()) ) {
//                    // wx扫码请求的 /login 没有username参数 只有code
//                    methodSignature.getParameterNames();
//                    //参数名称
//                    String[] argNames = methodSignature.getParameterNames();
//                    //参数值
//                    Object[] argValues = joinPoint.getArgs();
//                    Map<String, Object> paramMap = new HashMap<>();
//                    if (argValues != null) {
//                        for (int i = 0; i < argValues.length; i++) {
//                            paramMap.put(argNames[i], argValues[i]);
//                        }
//                    }
//                    if (!paramMap.isEmpty()) {
//                        userName = "用户登录";
//                    }
//                }
//            }
//
//
//            //开始获取ip时间
//            long start = System.currentTimeMillis();
//            String str = "";
//            try {
//                str =  IpUtil.getBrowser(request);
//            }catch (Exception ex) {
//                log.error("logAfterThrowing -- error",ex);
//            }
//            //结束获取ip时间
//            long end = System.currentTimeMillis();
//            //得到获取ip用了多长时间
//            long time = (end - start);
//            //以毫秒为单位打印
//            log.debug("<== 获取ip耗时：{}毫秒", time);
//
//            logService.save(userName, str, IpUtil.getIpAddr(request), joinPoint, sysLog);
//            Map<String,Object> logMap = new HashMap<>(8);
//            logMap.put("url",sysLog.getRequestPath());
//            logMap.put("method",sysLog.getMethod());
//            logMap.put("parameter",sysLog.getParameter());
//            logMap.put("time",sysLog.getTime());
//            logMap.put("description",sysLog.getDescription());
            //将日志记录到logstash logstash会自动将日志发送到REDIS
            //log.info(Markers.appendEntries(logMap), sysLog.toString());
            // log.info(sysLog.toString());
        }catch (Exception e) {
            log.error("logAround - exception ---- error",e);
            return result;
        }finally {
            if (currentTime != null) {
                currentTime.remove();
            }
        }
        return result;
    }

    /**
     * 配置异常通知
     *
     * @param joinPoint join point for advice
     * @param e         exception
     * @author blank
     * @date 2021-3-4 上午 10:33
     */
    @AfterThrowing(pointcut = "logPointCut()", throwing = "e")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
        try {
//            SysOperationLogEntity sysLog = new SysOperationLogEntity(OperationLogTypeEnum.ERROR, System.currentTimeMillis() - currentTime.get());
//            sysLog.setException(getStackTrace(e));
//            HttpServletRequest request = RequestHolder.getHttpServletRequest();
//            LoginUser currentUser = LoginUserUtil.getLoginUser();
//            String userName = "";
//            if (currentUser != null) {
//                userName = currentUser.getUserName();
//            } else {
//                userName = "SYSTEM";
//            }
//            String str = "";
//            str =  IpUtil.getBrowser(request);
//            logService.save(userName, str, IpUtil.getIpAddr(request), (ProceedingJoinPoint) joinPoint, sysLog);
//            log.error(sysLog.toString());
        }catch (Exception ex) {
            log.error("ogAfterThrowing -- error",ex);
            throw  ex;
        }finally {
            if (currentTime != null) {
                currentTime.remove();
            }
        }
    }

    /**
     * 获取堆栈信息
     */
    public static String getStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        try (PrintWriter pw = new PrintWriter(sw)) {
            throwable.printStackTrace(pw);
            return sw.toString();
        }
    }

}
