package com.github.wxiaoqi.security.common.log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.log.entity.XxLogEntity;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
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.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 javax.servlet.http.HttpServletResponse;

/**
 * Created by zhoujianwei
 * cas 项目注解相关拦截器
 * Date : 2018/6/6.
 * Time : 18:13
 */
@Aspect
@Component
@Slf4j
public class XxLogInterceptor{

    @Autowired
    CommonLogService commonLogService;

    //触发条件为：com.xxfc.platform包下面所有controller
    @Around("within(com.xxfc.platform.*.rest..* || com.xxfc.platform.*.controller..* || com.github.wxiaoqi.security.admin.rest..* || com.github.wxiaoqi.security.admin.rest..*)")
    public Object doAroundXxControllerLog(ProceedingJoinPoint pjp) throws Throwable {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();//获取request
        HttpServletResponse response = servletRequestAttributes.getResponse();//获取response

        //request 获得头部

        XxLogEntity xxLogEntity = new XxLogEntity();
        commonLogService.initCommonLogPrePart(xxLogEntity, request, pjp);

        Object[] params = pjp.getArgs();//获取请求参数
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        if(params != null && params.length > 0) {
            try{
                xxLogEntity.setRequestData(JSON.toJSONString(params[0]));
            }catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        Object result = new Object();
        try{
            //###################上面代码为方法执行前#####################
            result  = pjp.proceed();//执行方法，获取返回参数
            log.info("接口调用返回：{}", xxLogEntity.toString());
            //###################下面代码为方法执行后#####################
            if(result instanceof JSONObject) {
                commonLogService.initCommonLogLastPart(xxLogEntity, ((JSONObject) result).toJSONString());
            }else{
                commonLogService.initCommonLogLastPart(xxLogEntity, result);
            }
        }catch (BaseException  e){
            commonLogService.initCommonLogLastPart(xxLogEntity, ObjectRestResponse.createFailedResult(e.getStatus(), e.getMessage()));
            throw e;
        }catch (Exception e){
            commonLogService.initCommonLogLastPart(xxLogEntity, ObjectRestResponse.createFailedResult(500, e.getMessage()));
            throw e;
        }finally {
            commonLogService.commonLog(xxLogEntity);
        }


        return result;
    }

//    @Around("within(com.github.wxiaoqi.security.security.gate.filter..*)")
//    public Object doAroundXxControllerLog(ProceedingJoinPoint pjp) throws Throwable {
//
//    }

//    //casEipMsgErrDeal：外联报错消息处理
//    @AfterReturning(value = "within(com.ht.cas.*.*.*.*) && @annotation(casEipMsgErrDeal)", returning = "result")
//    public Result doAfterCasEipMsgErrDeal(JoinPoint jp, Result result, CasEipMsgErrDeal casEipMsgErrDeal) {
//        String msg = result.getMsg();
//        if(StringUtils.isBlank(msg)) {
//            msg = result.getCodeDesc();
//        }
//        //returnCode不为EIP_SUCCESS_CODE 并且 msg 没有信息
//        if(!CommonConstant.EIP_SUCCESS_CODE.equals(result.getReturnCode())) {
//            result.setData(null);
//            if(StringUtils.isBlank(msg)) {
//                Map map = ((List<Map>)result.getData()).get(0);
//                msg = map.get("field").toString() + " " + map.get("defaultMessage");
//            }
//        }
//        result.setMsg(msg);
//        return result;
//    }
//
//    //casMqSenderLog：mq发送消息
//    @Around(value = "within(com.ht.cas..*) && @annotation(casMqSenderLog)")
//    public void doAfterCasMqSenderLog(ProceedingJoinPoint pjp, CasMqSenderLog casMqSenderLog) {
//
//    }
//
//    //casMqSenderLog：mq接收消息
//    @Around(value = "within(com.ht.cas..*) && @annotation(casMqReceiverLog)")
//    public void doAfterCasMqLog(ProceedingJoinPoint pjp, CasMqReceiverLog casMqReceiverLog) {
//
//    }
//
//
//    // defined aop pointcut
//    @Pointcut("execution(* com.ht.cas.common.feignClient.*.*(..))")
//    public void casFeignClientLog() {
//    }
//
//
//    //@Around("casFeignClientLog()")
//    public Object doAroundCasFeignClientLog(ProceedingJoinPoint pjp) throws Throwable {
//        //request 获得头部
//        Signature signature = pjp.getSignature();
//        MethodSignature methodSignature = (MethodSignature)signature;
//        Method targetMethod = methodSignature.getMethod();
//
//        XxLogEntity xxLogEntity = new XxLogEntity();
//        commonLogService.initFeignClientLogPrePart(xxLogEntity, targetMethod);
//
//        Object[] params = pjp.getArgs();//获取请求参数
//
//        if(params != null && params.length > 0) {
//            xxLogEntity.setRequestData(JSON.toJSONString(params[0]));
//        }
//        Object result = new Object();
//        try{
//            //###################上面代码为方法执行前#####################
//            result  = pjp.proceed();//执行方法，获取返回参数
//            //###################下面代码为方法执行后#####################
//            commonLogService.initCommonLogLastPart(xxLogEntity, (Result) result);
//        }catch (Exception e){
//            commonLogService.initCommonLogLastPart(xxLogEntity, (Result) result);
//            xxLogEntity.setResponseData(JSON.toJSONString(ResultHelper.buildFail(e.getMessage())));
//            throw e;
//        }finally {
//            commonLogService.commonLog(xxLogEntity);
//        }
//
//        return result;
//    }


}
