package com.yeejoin.amos.boot.module.jxiop.biz.core.framework;

import com.alibaba.fastjson.JSON;
import com.yeejoin.amos.boot.module.jxiop.biz.service.IPermissionService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

/**
 * @author keyong
 * @title: GatewayIdAutowiredAspect
 * <pre>
 * @description: TODO
 * </pre>
 * @date 2024/1/25 10:21
 */
@Component
@Aspect
public class GatewayIdAutowiredAspect {

    private static final transient Logger log = LoggerFactory.getLogger(GatewayIdAutowiredAspect.class);

    @Autowired
    private IPermissionService permissionService;

    @Before(value = "@annotation(com.yeejoin.amos.boot.module.jxiop.biz.core.framework.GatewayIdAutowired) && @annotation(gatewayIdAutowired)")
    public void doBefore(JoinPoint joinPoint, GatewayIdAutowired gatewayIdAutowired) {
        if (gatewayIdAutowired.isNeedGatewayId()) {
            try {
                //获取入参列表
                Object[] args = joinPoint.getArgs();
                log.info("args: {}", JSON.toJSONString(args));
                //入参判空
                if (null == args || args.length == 0) {
                    log.info("No fields!");
                    return;
                }
                // 只有一个参数主要针对@RequestBody，一般只会有一个入参，若遇到多个@RequestParam，需循环处理
                if (args.length == 1) {
                    Object arg = args[0];
                    List<String> ids = permissionService.getCurrentUserPermissions();
//                    List<String> ids = Arrays.asList("1668801435891929089");
                    //获取字段域
                    Field[] fields = arg.getClass().getDeclaredFields();
                    log.info("getDeclaredFields: {}", JSON.toJSONString(fields));
                    if (Arrays.stream(fields).noneMatch(item -> "gatewayIds".equals(item.getName()))) {
                        log.info("No gatewayId field !!!");
                        return;
                    }
                    //入参中有"gatewayIds"，获取该字段
                    Field field = arg.getClass().getDeclaredField("gatewayIds");
                    //判断是否可使用
                    boolean accessible = ((!Modifier.isPublic(field.getModifiers())
                            || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
                            || Modifier.isFinal(field.getModifiers())) && !field.isAccessible());
                    //若不可用，则需要进行setAccessible
                    if (accessible) {
                        ServletRequestAttributes attributes
                                = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                        // 获取request对象
                        HttpServletRequest request = attributes.getRequest();
                        log.info("Method name: {}", request.getRequestURI());
                        field.setAccessible(true);
                        //参数替换
                        field.set(arg, ids);
                    }
                }
                // 若是get方法，有多个参数则需要扩展
            } catch (Exception e) {
                log.error("切面参数设置异常", e);
            }
        }
    }

}
