package com.elab.log.asepct;

import com.alibaba.fastjson.JSON;
import com.dianping.cat.Cat;
import com.elab.core.bean.Info;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * 日志出参添加定义
 * <p>
 * 目的是将返回值中植入CAT的日志编号,方便调用方可以直接通过logId直接查询
 *
 * @author : liukx
 * @create : 2018/5/31 15:03
 * @email : liukx@elab-plus.com
 */
@ControllerAdvice
public class LogResponseBodyAdvice implements ResponseBodyAdvice {

    private Logger logger = LoggerFactory.getLogger(LogResponseBodyAdvice.class);
    /**
     * 出参字段的名称定义
     */
    private String logId = "logId";

    public void setLogId(String logId) {
        this.logId = logId;
    }

    /**
     * @param returnType
     * @param converterType
     * @return
     */
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    /**
     * body参数写入之前
     *
     * @param body                  原始类型
     * @param returnType            返回类型
     * @param selectedContentType   查询类型
     * @param selectedConverterType 转换类型
     * @param request
     * @param response
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        try {
            if (body != null) {
                if (body instanceof Info) {
                    Info info = (Info) body;
                    String currentMessageId = Cat.getCurrentMessageId();
                    Map<String, Object> extension = info.getExtension();
                    if (extension == null) {
                        extension = new HashMap<String, Object>(8);
                        info.setExtension(extension);
                    }
                    info.getExtension().put(this.logId, currentMessageId);
                } else {
                    BeanUtils.setProperty(body, this.logId, Cat.getCurrentMessageId());
                }
            }
        } catch (Exception e) {
            logger.error("===========赋值参数出现故障==============" + JSON.toJSONString(body), e);
        }
        return body;
    }
}
