package com.bcxin.web.commons;

import com.bcxin.Infrastructures.TenantContext;
import com.bcxin.Infrastructures.TenantUserContext;
import com.bcxin.Infrastructures.exceptions.*;
import com.bcxin.Infrastructures.utils.ExceptionUtil;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.filter.ExceptionFilter;


@Activate(group = CommonConstants.PROVIDER)
public class GlobalExceptionFilter extends ExceptionFilter {
    public GlobalExceptionFilter() {
        System.out.println("GlobalExceptionFilter");
    }

    /**
     * 执行调用之前先绑定当前登入用户信息
     * @param invoker
     * @param invocation
     * @return
     * @throws RpcException
     */
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Object data = invocation.getObjectAttachment(TenantUserContext.CURRENT_TENANT_USER_INFO);
        if (data != null) {
            TenantContext.getInstance().getUserContext().init((TenantUserContext.UserModel) data);
        }

        return super.invoke(invoker, invocation);
    }

    @Override
    public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
        /**
         * 当异常为非自定义异常的时候，直接走dubbo默认的异常机制
         */
        if (appResponse.hasException()) {
            if (!ExceptionUtil.is(appResponse.getException(), TenantExceptionAbstract.class)) {
                super.onResponse(appResponse, invoker, invocation);
            } else {
                /**
                 * 没有指定的话; 系统将报RpcException
                 */
                /*
                if (ExceptionUtil.is(appResponse.getException(), TenantExceptionAbstract.class)) {
                    appResponse.setException(appResponse.getException());
                } else {
                    appResponse.setException(new RuntimeException(appResponse.getException().getMessage(), appResponse.getException()));
                }
                 */
                if (ExceptionUtil.is(appResponse.getException(), ForbidTenantException.class)) {
                    appResponse.setException(new ForbidTenantException(appResponse.getException().getMessage()));
                } else if (ExceptionUtil.is(appResponse.getException(), NotAllowedTenantException.class)) {
                    appResponse.setException(new NotAllowedTenantException(appResponse.getException().getMessage()));
                }  else if (ExceptionUtil.is(appResponse.getException(), AccountLockedException.class)) {
                    appResponse.setException(new AccountLockedException(appResponse.getException().getMessage()));
                }   else if (ExceptionUtil.is(appResponse.getException(), AbnormalPersonnelException.class)) {
                    AbnormalPersonnelException abnormalPersonnelException = (AbnormalPersonnelException) appResponse.getException();
                    appResponse.setException(new AbnormalPersonnelException(abnormalPersonnelException.getCode(), abnormalPersonnelException.getMessage(), abnormalPersonnelException.getExceptionList()));
                } else if (ExceptionUtil.is(appResponse.getException(), ConflictTenantException.class)) {
                    appResponse.setException(new ConflictTenantException(appResponse.getException().getMessage()));

                } else if (ExceptionUtil.is(appResponse.getException(), UnAuthorizedTenantException.class)) {
                    appResponse.setException(new UnAuthorizedTenantException(appResponse.getException().getMessage()));
                } else if (ExceptionUtil.is(appResponse.getException(), ConfirmCheckStatusException.class)) {
                    ConfirmCheckStatusException ck = (ConfirmCheckStatusException) appResponse.getException();
                    appResponse.setException(new ConfirmCheckStatusException(ck.getTenantUserId(), ck.getCheckedStatus(), ck.getMessage()));
                } else if (ExceptionUtil.is(appResponse.getException(), TenantExceptionAbstract.class)) {
                    appResponse.setException(new BadTenantException(appResponse.getException().getMessage()));
                } else {
                    appResponse.setException(new RuntimeException(appResponse.getException().getMessage()));
                }
            }
        }

        //super.onResponse(appResponse, invoker, invocation);
    }

    @Override
    public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) {
        super.onError(e, invoker, invocation);
    }
}
