package org.dromara.wflow.config;

import cn.dev33.satoken.exception.NotLoginException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import org.dromara.common.core.domain.R;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.wflow.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.FlowableException;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

/**
 * @author : willian fu
 * @date : 2022/6/27
 */
@Slf4j
@Component(value = "wflowGlobalExceptionHandler")
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(BusinessException.class)
    public R<Void> businessExceptionHandler(BusinessException e){
        log.error("BusinessException：", e);
        return R.fail(e.getMessage());
    }

    @ExceptionHandler(NotLoginException.class)
    @ResponseStatus(org.springframework.http.HttpStatus.UNAUTHORIZED)
    public String LoginExceptionHandler(NotLoginException e){
        log.error("NotLoginException：", e);
        return JsonUtils.toJsonString(R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败，无法访问系统资源"));
    }

    @ExceptionHandler(FlowableException.class)
    public R<Void> flowableExceptionHandler(FlowableException e){
        log.error("FlowableException：", e);
        String error = "流程执行异常: " + e.getMessage();
        if (StrUtil.isNotBlank(e.getMessage())){
            if (e.getMessage().contains("No outgoing sequence")){
                error = "下方条件分支所有条件都不满足，流程无法继续执行，请检查";
            } else if (e.getMessage().contains("Couldn't deserialize object in variable")) {
                error = "流程变量[ " + e.getMessage().substring(40) + " ]无法反序列化成对象，请检查";
            }
            //其他情况继续加else
        }
        return R.fail(error);
    }

    @ExceptionHandler(Exception.class)
    public R<Void> runtimeExceptionHandler(Exception e){
        log.error("RuntimeException：", e);
        return R.fail(e.getMessage());
    }
}
