package cn.sh.stc.sict.cloud.common.security.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.upms.dto.CurrentUser;
import cn.sh.stc.sict.cloud.upms.model.SysLog;
import io.swagger.annotations.ApiOperation;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 系统日志工具类
 *
 * @author F_xh
 */
@Slf4j
@UtilityClass
public class SysLogUtils {
    public SysLog getSysLog(JoinPoint point) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects
                .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        CurrentUser currentUser = SecurityUtils.getCurrentUser();
        String clientId = SecurityUtils.getClientId();
        SysLog sysLog = new SysLog();
        sysLog.setCreateBy(currentUser.getName());
        sysLog.setType(Constant.BYTE_NO);
        sysLog.setRemoteAddr(ServletUtil.getClientIP(request));
        sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
        sysLog.setMethod(request.getMethod());
        sysLog.setUserAgent(request.getHeader("user-agent"));
        sysLog.setParams(HttpUtil.toParams(request.getParameterMap()));
        sysLog.setServiceId(request.getHeader("X-Forwarded-Prefix"));
        sysLog.setCreateUserId(0L);
        if (ObjectUtil.isNotNull(point)) {
            Object[] args = point.getArgs();
            if (args.length > 0) {
                Map map = SysLogUtils.getKeyAndValue(args[0]);
                sysLog.setParams(sysLog.getParams() + JSONUtil.toJsonStr(map));
            }
            sysLog.setTitle(SysLogUtils.getTitle(point, request));
        }
        return sysLog;
    }

    public static Map<String, Object> getKeyAndValue(Object obj) {
        Map<String, Object> map = new HashMap<>();
        try {
            // 得到类对象
            Class userCla = (Class) obj.getClass();
            /* 得到类中的所有属性集合 */
            Field[] fs = userCla.getDeclaredFields();
            for (int i = 0; i < fs.length; i++) {
                Field f = fs[i];
                f.setAccessible(true);
                Object val = new Object();
                try {
                    val = f.get(obj);
                    // 得到此属性的值
                    map.put(f.getName(), val);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }catch (Exception ex){
            log.error(ex.getMessage(), ex);
        }
        return map;
    }

    public static String getTitle(JoinPoint joinPoint, HttpServletRequest request) {
        Method method = getMethod(joinPoint);
        ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
        String value = "";
        if (null != apiOperation) {
            value = apiOperation.value();
        }
        return value;
    }

    private Method getMethod(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        return methodSignature.getMethod();
    }
}
