package com.lunhan.xxx.host.api;

import com.google.common.base.Charsets;
import com.lunhan.xxx.common.enums.ELogger;
import com.lunhan.xxx.common.enums.EResultCode;
import com.lunhan.xxx.common.ExecutedResult;
import com.lunhan.xxx.common.exceptions.BusinessException;
import com.lunhan.xxx.common.util.*;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger sysLogger = LoggerUtil.get(ELogger.SYS_ERROR);
    private static final Logger logger = LoggerUtil.get(ELogger.API_REQUEST);
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ExecutedResult<String> handle(Exception e) {
        ExecutedResult<String> result = new ExecutedResult<>(EResultCode.ERROR, "", e.getMessage());

        // 记录请求日志
        this.writeLog(result);

        sysLogger.error("SysError", e);
        return result;
    }


    @ResponseBody
    @ExceptionHandler(value = BusinessException.class)
    public ExecutedResult<String> handle(BusinessException e) {
        ExecutedResult<String> result = new ExecutedResult<>(e.getCode(), "", e.getMessage());

        // 记录请求日志
        this.writeLog(result);

        return result;
    }

    private void writeLog(ExecutedResult<String> result) {
        //获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (null == attributes) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        String data;
        try {
            byte[] buffer = HttpUtil.getBytesFromInputStream(request.getInputStream());
            data = new String(buffer, Charsets.UTF_8);
        } catch (Exception e) {
            data = "";
        }
        ApiRequestLogDTO webLog = HttpRequestLogPool.getRequestInfo();
        if (null == webLog) {
            return;
        }
        String log = String.format("[%s]" +
                        "%nrequestPath: %s[%s]" +
                        "%nreponseData: %s" +
                        "%nrequestTime: %s" +
                        "%nresponseTime: %s" +
                        "%nspendTime: %s" +
                        "%nmethod: %s" +
                        "%nrequestIp: %s" +
                        "%ntokenCode: %s" +
                        "%nrequestData: %s",

                "",
                webLog.getPath(),
                "",
                SerializeUtil.toJson(result),
                LocalDateTimeUtil.toFormatFullString(webLog.getRequestTime()),
                LocalDateTimeUtil.nowDateTimeFullStr(),
                LocalDateTimeUtil.nowTimeStamp() - webLog.getRequestTime(),
                webLog.getMethod(),
                webLog.getRequestIP(),
                webLog.getRequestToken(),
                data
        );
        logger.info(log);
    }
}