package com.gic.haoban.manage.web.exception;

import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.haoban.base.api.common.ShowFrontMessageException;
import com.gic.haoban.common.utils.HaobanResponse;
import com.gic.haoban.manage.web.controller.WebBaseController;
import com.gic.haoban.manage.web.errCode.HaoBanErrCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created 2018/7/24.
 *
 * @author hua
 */
@ControllerAdvice
public class GlobalExceptionHandler extends WebBaseController {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    private static final Pattern pattern = Pattern.compile("(.*: )(.*)(\\n.*)");

    /**
     * 控制器运行异常
     */
    @ResponseBody
    @ExceptionHandler(RuntimeException.class)
    public HaobanResponse controllerRunException(HttpServletResponse response, RuntimeException ex) {
        logger.error("controllerRunException:{}", ex.getMessage(), ex);
        HaobanResponse res = new HaobanResponse();
        res.setErrorCode(HaoBanErrCode.ERR_3.getCode());
        String message = ex.getMessage();
        if (message != null && message.indexOf(ShowFrontMessageException.class.getName()) > -1) {
            Matcher matcher = pattern.matcher(message);
            while (matcher.find()) {
                message = (matcher.group(2));
            }
        } else {
            message = HaoBanErrCode.ERR_3.getMsg();
        }
        res.setMessage(message);
        return res;
    }

    /**
     * 全局异常
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public HaobanResponse controllerException(HttpServletResponse response, Exception ex) {
        logger.error("controllerException:{}", ex.getMessage(), ex);
        StringBuilder sb = new StringBuilder();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (PrintWriter printWriter = new PrintWriter(baos)) {
            ex.printStackTrace(printWriter);
        }
        try {
            sb.append(baos.toString());
        } catch (Exception ignored) {
        }
        if (sb.length() == 0) {
            sb.append(ex.getMessage());
        }
        return resultResponse(HaoBanErrCode.ERR_3);
    }

    /**
     * valid 异常告警
     *
     * @param response
     * @param ex
     * @return {@link HaobanResponse }
     * @author mozhu
     * @date 2021-12-15 14:55:40
     */
    @ResponseBody
    @ExceptionHandler(BindException.class)
    public HaobanResponse bindException(HttpServletResponse response, BindException ex) {
        logger.error("bindException:{}", ex.getMessage());
        HaoBanErrCode errCode = HaoBanErrCode.ERR_5;
        BindingResult bindingResult = ex.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        return resultResponse(errCode, null, fieldError.getField() + fieldError.getDefaultMessage());
    }

    @ResponseBody
    @ExceptionHandler(TargetException.class)
    public RestResponse bindException(HttpServletResponse response, TargetException ex) {
        return RestResponse.failure(String.valueOf(HaoBanErrCode.ERR_3.getCode()), ex.getMessage());
    }

    /**
     * valid 异常告警 @ReuqestBody
     *
     * @param response
     * @param ex
     * @return {@link HaobanResponse }
     * @author mozhu
     * @date 2021-12-15 14:55:35
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public HaobanResponse methodArgumentNotValidException(HttpServletResponse response, MethodArgumentNotValidException ex) {
        logger.error("methodArgumentNotValidException:{}", ex.getMessage());
        HaoBanErrCode errCode = HaoBanErrCode.ERR_5;
        BindingResult bindingResult = ex.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        return resultResponse(errCode, null, fieldError.getField() + fieldError.getDefaultMessage());
    }

    /**
     * 登录异常
     *
     * @param response 响应
     * @param ex
     * @return {@link HaobanResponse }
     * @author mozhu
     * @date 2021-12-15 14:55:16
     */
    @ResponseBody
    @ExceptionHandler(NoLoginException.class)
    public HaobanResponse controllerNoLoginException(HttpServletResponse response, NoLoginException ex) {
        return resultResponse(HaoBanErrCode.ERR_4);
    }
}
