package com.sckw.sentinel;


import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.response.HttpResult;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

/**
 * @author lfdc
 * @version 1.0
 * @className CustomBlockExceptionHandler
 * @description 自定义sentinel异常Handler
 * @company sckw
 * @date 2023-06-08 09:06:59
 */

@Slf4j
@Configuration
public class CustomBlockExceptionHandler implements BlockExceptionHandler {
    HttpResult httpResult = null;
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        log.info("urlBlock.......................");
        //不同的异常返回不同的提示语
        //FlowException  //限流异常
        //DegradeException  //降级异常
        //ParamFlowException //参数限流异常
        //SystemBlockException //系统负载异常
        //AuthorityException //授权异常
        boolean einstanceof;
        if (e instanceof FlowException) {
            httpResult.setCode(HttpStatus.CODE_60701);
            httpResult.setMsg(HttpStatus.FLOW_EXCEPTION_ERROR_MESSAGE);

        } else if (e instanceof DegradeException) {
            httpResult.setCode(HttpStatus.CODE_60801);
            httpResult.setMsg(HttpStatus.DEGRADE_EXCEPTION_ERROR_MESSAGE);

        } else if (e instanceof ParamFlowException) {
            httpResult.setCode(HttpStatus.CODE_60901);
            httpResult.setMsg(HttpStatus.PARAM_FLOW_EXCEPTION_ERROR_MESSAGE);

        } else if (e instanceof SystemBlockException) {
            httpResult.setCode(HttpStatus.CODE_601001);
            httpResult.setMsg(HttpStatus.SYSTEM_BLOCK_EXCEPTION_ERROR_MESSAGE);
        } else if (e instanceof AuthorityException) {
            httpResult.setCode(HttpStatus.CODE_601101);
            httpResult.setMsg(HttpStatus.AUTHORITY_EXCEPTION_ERROR_MESSAGE);
        } else {
            //其他规则
            httpResult.setCode(HttpStatus.CODE_601201);
            httpResult.setMsg(HttpStatus.OTHER_EXCEPTION_ERROR_MESSAGE);
        }
    }

    public static HttpResult sentinelFlowBlock(BlockException ex){
        log.info("flowException ERROR:{}",ex.getRule(),ex);
        return HttpResult.error(HttpStatus.CODE_60701, HttpStatus.FLOW_EXCEPTION_ERROR_MESSAGE);
    }

    public static HttpResult sentinelDegradeBlock(BlockException ex){
//        log.info("sentinelDegradeDemo进入熔断");
        log.info("degradeException ERROR:{}",ex.getRule(),ex);
        return HttpResult.error(HttpStatus.CODE_60801, HttpStatus.DEGRADE_EXCEPTION_ERROR_MESSAGE);
    }

    public static HttpResult sentinelParamFlowBlock(BlockException ex){
        log.info("paramFlowException ERROR:{}",ex.getRule(),ex);
        return HttpResult.error(HttpStatus.CODE_60901, HttpStatus.PARAM_FLOW_EXCEPTION_ERROR_MESSAGE);
    }

    public static HttpResult sentinelSystemBlock(BlockException ex){
        log.info("systemException ERROR:{}",ex.getRule(),ex);
        return HttpResult.error(HttpStatus.CODE_601001, HttpStatus.SYSTEM_BLOCK_EXCEPTION_ERROR_MESSAGE);
    }

    public static HttpResult sentinelAuthorityBlock(BlockException ex){
        log.info("authorityException ERROR:{}",ex.getRule(),ex);
        return HttpResult.error(HttpStatus.CODE_601101,HttpStatus.AUTHORITY_EXCEPTION_ERROR_MESSAGE);
    }


    public static HttpResult sentinelOtherBlock(BlockException ex){
        log.info("otherException ERROR:{}",ex.getRule(),ex);
        return HttpResult.error(HttpStatus.CODE_601201, HttpStatus.OTHER_EXCEPTION_ERROR_MESSAGE);
    }

    @PostConstruct
    public void init() {
        new CustomBlockExceptionHandler();
    }
}
