package com.crm.gateway.configuration;

import com.crm.gateway.exception.*;
import com.crm.rely.backend.core.constant.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.HttpMessageNotReadableException;
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.servlet.NoHandlerFoundException;

import javax.servlet.ServletException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * controller异常捕获
 */
@ControllerAdvice
public class ControllerExceptionAdvice {

    @Autowired
    private LocaleMessage localeMessage;


    /**
     * 获取配置 用于判断系统是否开发环境 若是开发环境这将异常完全抛到页面 无需打开日志查看
     */
    @Autowired
    private Environment environment;

    private static final String CODE = "code";
    private static final String MSG = "msg";

    /**
     * service运行时异常处理 自动捕获到controller的所有异常 并进行处理返回前端
     *
     * @param e 异常
     * @return 返回到页面的处理结果
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Map controllerExceptionHandler(Exception e) throws IOException {
        if (isDev()) {
            e.printStackTrace();
        }
        int code = Constants.FAILED_CODE;
        String msg = null;
        //判断是否404 500异常
        if (e instanceof NoHandlerFoundException) {
            code = Constants.FAILED_CODE_404;
            msg = e.getMessage();
        } else if (e instanceof ServletException) {
            code = Constants.SYSTEM_ERROR_CODE;
            msg = e.getMessage();
        }
        if (e instanceof HttpMessageNotReadableException) {
            code = Constants.FAILED_CODE;
            msg = Constants.PARAMETER_ERROR;
        } else if (e instanceof RuntimeException) {
            code = Constants.SYSTEM_ERROR_CODE;
            msg = Constants.SYSTEM_ERROR;
        }


        //判断登录异常 抛出登录过期 登录错误等 否则判断是否逻辑异常 如果异常 直接取到填写的结果
        if (e instanceof LoginException) {
            code = Constants.UNLOGIN_CODE;
            msg = e.getMessage();
        } else if (e instanceof ServiceException || e instanceof ControllerException || e instanceof PayValidatedException || e instanceof DataNotFoundException) {
            msg = e.getMessage();
        }

        if (e instanceof RuntimeException) {
            code = Constants.SYSTEM_ERROR_CODE;
        }

        Map map = new HashMap(2);
        map.put(CODE, code);
        map.put(MSG, localeMessage.getMessage(msg, msg));
        return map;
    }


    /**
     * 判断是否是本地环境
     *
     * @return
     */
    private boolean isDev() {
        if (environment.getActiveProfiles() == null || environment.getActiveProfiles().length <= 0) {
            return false;
        }
        for (String value : environment.getActiveProfiles()) {
            if (value.equals("dev")) {
                return true;
            }
        }
        return false;
    }
}
