package com.srs.dormitory.aspect;

import com.alibaba.druid.support.json.JSONUtils;
import com.srs.common.core.domain.model.LoginUser;
import com.srs.common.utils.SecurityUtils;
import com.srs.dormitory.domain.DmsOperLog;
import com.srs.dormitory.service.IDmsOperLogService;
import com.srs.dormitory.utils.DmsOperationLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
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.io.BufferedReader;
import java.io.IOException;
import java.time.LocalDateTime;

@Aspect
@Component
public class OperationLogAspect {
    @Autowired
    private IDmsOperLogService dmsOperLogService;

    @Pointcut("@annotation(dmsOperationLog)")
    public void operationLogPointcut(DmsOperationLog dmsOperationLog) {
    }

    @AfterReturning(value = "operationLogPointcut(dmsOperationLog)", returning = "result", argNames = "joinPoint,dmsOperationLog,result")
    public void afterOperation(JoinPoint joinPoint, DmsOperationLog dmsOperationLog, Object result) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        DmsOperLog log = new DmsOperLog();
        String content = "",title = "";
        if (dmsOperationLog.content()!=null){
            content = dmsOperationLog.content();
        }
        if (dmsOperationLog.title()!=null){
            title = dmsOperationLog.title();
        }
        log.setOperIp(loginUser.getIpaddr());
        log.setOperLocation(loginUser.getLoginLocation());
        log.setOperName(loginUser.getUsername());
        log.setMethod(joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName()+"()");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        log.setOperParam(getJsonStringFromRequest(request));
        log.setRequestMethod(request.getMethod());
        log.setOperUrl(request.getRequestURI());
        log.setStatus(0);
        log.setTitle(title);
        log.setContent(loginUser.getUsername()+content);
        log.setOperTime(LocalDateTime.now());
        log.setJsonResult(JSONUtils.toJSONString(result));
        dmsOperLogService.save(log);
    }
    @AfterThrowing(value = "operationLogPointcut(dmsOperationLog)",throwing = "throwable", argNames = "joinPoint,dmsOperationLog,throwable")
    public void afterThrowing(JoinPoint joinPoint, DmsOperationLog dmsOperationLog, Throwable throwable){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        DmsOperLog log = new DmsOperLog();
        String content = "",title = "";
        if (dmsOperationLog.content()!=null){
            content = dmsOperationLog.content();
        }
        if (dmsOperationLog.title()!=null){
            title = dmsOperationLog.title();
        }
        log.setOperIp(loginUser.getIpaddr());
        log.setOperLocation(loginUser.getLoginLocation());
        log.setOperName(loginUser.getUsername());
        log.setMethod(joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName()+"()");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        log.setOperParam(getJsonStringFromRequest(request));
        log.setRequestMethod(request.getMethod());
        log.setOperUrl(request.getRequestURI());
        log.setStatus(1);
        log.setTitle(title);
        log.setContent(loginUser.getUsername()+content);
        log.setErrorMsg(throwable.getMessage());
        log.setOperTime(LocalDateTime.now());
        dmsOperLogService.save(log);
    }

    // 辅助方法，从HttpServletRequest中读取JSON字符串
    private String getJsonStringFromRequest(HttpServletRequest request) {
        try {
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = request.getReader();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

}
