package com.ruoyi.aicall.aspect;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aicall.utils.ClientIpCheck;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
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.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * ApiController IP whitelist check (api-client-white-ips)
 */
@Slf4j
@Aspect
@Order(1)
@Component
public class ApiClientIpAspect {

    private static final String NO_AUTH_MSG = "未授权，请联系系统管理员添加ip白名单！";

    @Around("execution(* com.ruoyi.aicall.controller.ApiController.*(..))")
    public Object checkClientIp(ProceedingJoinPoint pjp) throws Throwable {
        HttpServletRequest request = resolveRequest(pjp.getArgs());
        if (request != null && !ClientIpCheck.checkIp(request)) {
            Class<?> returnType = ((MethodSignature) pjp.getSignature()).getReturnType();
            return buildDeniedResult(returnType);
        }
        return pjp.proceed();
    }

    private HttpServletRequest resolveRequest(Object[] args) {
        if (args != null) {
            for (Object arg : args) {
                if (arg instanceof HttpServletRequest) {
                    return (HttpServletRequest) arg;
                }
            }
        }
        ServletRequestAttributes attrs =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return attrs == null ? null : attrs.getRequest();
    }

    private Object buildDeniedResult(Class<?> returnType) {
        if (TableDataInfo.class.isAssignableFrom(returnType)) {
            TableDataInfo tableDataInfo = new TableDataInfo();
            tableDataInfo.setTotal(0);
            tableDataInfo.setCode(AjaxResult.Type.NO_AUTH.value());
            tableDataInfo.setMsg(NO_AUTH_MSG);
            return tableDataInfo;
        }
        if (JSONObject.class.isAssignableFrom(returnType)) {
            JSONObject result = new JSONObject();
            result.put("code", AjaxResult.Type.NO_AUTH.value());
            result.put("msg", NO_AUTH_MSG);
            return result;
        }
        return AjaxResult.error(AjaxResult.Type.NO_AUTH, NO_AUTH_MSG, "");
    }
}