package com.reyun.saas.common.exception;

import com.reyun.saas.common.constants.PermitAllUrl;
import com.reyun.saas.common.restResult.RestResult;
import com.reyun.saas.common.restResult.ResultCode;
import com.reyun.saas.common.restResult.ResultGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Controller异常处理->返回前端
 * 自定义异常处理来改变默认的客户端访问接口产生的异常信息
 */
@Slf4j
@ControllerAdvice
public class ControllerExceptionHandler {

    /**
     * 错误码
     */
    public static final String CODE = "code";

    /**
     * 消息
     */
    public static final String MESSAGE = "message";


    /**
     * 处理类型入参时json序列化异常
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public void handleMessageNotReadableException(Exception e, HttpServletResponse response,
                                             HttpServletRequest request) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = null;
        RestResult result = null;

        String servletPath = request.getServletPath();
        if (PermitAllUrl.OPENAPIURL.contains(servletPath)) {
            //统一处理openApi/cp的参数数据类型异常
            result =new RestResult(ResultCode.REQUEST_PARAM_ERROR);
        }else{
            //其他接口的参数异常
            result =new RestResult(ResultCode.PARAMETER_ERROR);
        }

        try {
            // 重置response的输出流
            // response.reset();
            writer = response.getWriter();
            writer.print(result.toJson());
            writer.flush();
        } catch (IOException e1) {
            log.error(e1.getMessage(),e1);
        }
        log.error(e.getMessage(),e);
    }

    /**
     * 处理异常的类型
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(Exception.class)
    public void handleCustomException(Exception e, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = null;
        RestResult result = null;
        if (e instanceof CustomException) {
            // 可设置不同的HTTP状态
            response.setStatus(200);
            CustomException ex = (CustomException) e;
            result = new RestResult(ex.getResultCode());
        } else if (e instanceof RuntimeException) {
            response.setStatus(500);
            result = ResultGenerator.genFailResult(e.getMessage());
        } else {
            response.setStatus(500);
            result = new RestResult(500, "未知错误，请联系管理员");
        }
        try {
            // 重置response的输出流
            // response.reset();
            writer = response.getWriter();
            writer.print(result.toJson());
            writer.flush();
        } catch (IOException e1) {
            log.error(e1.getMessage(),e1);
        }
        log.error(e.getMessage(),e);
    }
}


