package cn.ezhizao.framework.interceptor;

import cn.ezhizao.common.utils.DateUtils;
import cn.ezhizao.common.utils.StringUtils;
import cn.ezhizao.framework.aspectj.lang.enums.DataSourceType;
import cn.ezhizao.framework.datasource.DynamicDataSource;
import cn.ezhizao.framework.datasource.DynamicDataSourceContextHolder;
import cn.ezhizao.project.tenant.domain.Tenant;
import cn.ezhizao.project.tenant.service.ITenantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 数据源拦截器
 *
 * @author devjd
 */

@Component
@Slf4j
public class TenantInterceptor implements HandlerInterceptor {

    @Resource
    private ITenantService tenantService;

    @Resource
    private DynamicDataSource dynamicDataSource;

    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getServletPath();
        String tenantId = request.getHeader("tenantId");
        String tenantName = request.getHeader("tenantName");
        String dataSourceType = null;
        log.info("&&&&&&&&&&&&&&&& 租户拦截 &&&&&&&&&&&&&&&&");
        if (StringUtils.isNotBlank(tenantId)) {
            dataSourceType = DataSourceType.TENANT.name();
                //搜索默认数据库，去注册租户的数据源，下次进来直接session匹配数据源
                Tenant tenant = tenantService.getById(tenantId);
            int disabled = 2;
            int vip = 1;
            if (tenant == null) {
                    throw new RuntimeException("无此租户:"+ tenantName );
                }else if(disabled == tenant.getStatus()){
                    throw new RuntimeException("租户["+ tenantName +"]已停用" );
                }else if(tenant.getExpire()!=null){
                    if(tenant.getExpire().before(DateUtils.getNowDate())){
                        throw new RuntimeException("租户["+tenantName+"]已过期");
                    }
                }else if(vip == tenant.getVip()){
                    if (!dynamicDataSource.existDataSource(tenantId)) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("driverClassName", driverClassName);
                    map.put("url", tenant.getDbUrl());
                    map.put("username", tenant.getDbUserName());
                    map.put("password", tenant.getDbPassword());
                    dynamicDataSource.addDataSource(tenantId, map);
                    log.info("&&&&&&&&&&& 已设置vip租户:{} 连接信息: {}", tenantName, tenant);
                    }else{
                        log.info("&&&&&&&&&&& 当前vip租户:{}", tenantName);
                    }
                    dataSourceType = tenantId;
                }
        }else{
            dataSourceType = DataSourceType.MASTER.name();
        }
        // 为了单次请求，多次连接数据库的情况，这里设置localThread，AbstractRoutingDataSource的方法去获取设置数据源
        DynamicDataSourceContextHolder.setDataSourceType(dataSourceType);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 请求结束删除localThread
        DynamicDataSourceContextHolder.clearDataSourceType();
    }
}
