package com.keyware.shandan.dynacmicform.config.spring;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoader;

@Component
@Lazy(false)
public class ContextHelper implements ApplicationContextAware {
    private static final Logger log = LoggerFactory.getLogger(ContextHelper.class);
    private static ApplicationContext APPLICATION_CONTEXT = null;
    private static String DATABASE_TYPE = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        APPLICATION_CONTEXT = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        if (APPLICATION_CONTEXT == null) {
            APPLICATION_CONTEXT = ContextLoader.getCurrentWebApplicationContext();
        }
        if (APPLICATION_CONTEXT == null) {
            log.warn("无法获取ApplicationContext，请在Spring初始化之后调用!");
        }
        return APPLICATION_CONTEXT;
    }

    /***
     * 获取指定类型的单个Bean实例
     * @param clazz
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        try {
            return getApplicationContext().getBean(clazz);
        } catch (Exception e) {
            log.debug("无法找到 bean: {}", clazz.getSimpleName());
            return null;
        }
    }

    /***
     * 获取JdbcUrl
     * @return
     */
    public static String getJdbcUrl() {
        Environment environment = getApplicationContext().getEnvironment();
        String jdbcUrl = environment.getProperty("spring.datasource.url");
        if (jdbcUrl == null) {
            jdbcUrl = environment.getProperty("spring.datasource.druid.url");
        }
        if (jdbcUrl == null) {
            String master = environment.getProperty("spring.datasource.dynamic.primary");
            if (master != null) {
                jdbcUrl = environment.getProperty("spring.datasource.dynamic.datasource." + master + ".url");
            }
        }
        if (jdbcUrl == null) {
            String names = environment.getProperty("spring.shardingsphere.datasource.names");
            if (names != null) {
                jdbcUrl = environment.getProperty("spring.shardingsphere.datasource." + names.split(",")[0] + ".url");
            }
        }
        return jdbcUrl;
    }

    /**
     * 获取数据库类型
     *
     * @return
     */
    public static String getDatabaseType() {
        if (DATABASE_TYPE != null) {
            return DATABASE_TYPE;
        }
        String jdbcUrl = getJdbcUrl();
        if (jdbcUrl != null) {
            DbType dbType = JdbcUtils.getDbType(jdbcUrl);
            DATABASE_TYPE = dbType.getDb();
            if (DATABASE_TYPE.startsWith(DbType.SQL_SERVER.getDb())) {
                DATABASE_TYPE = DbType.SQL_SERVER.getDb();
            }
        } else {
            SqlSessionFactory sqlSessionFactory = getBean(SqlSessionFactory.class);
            if (sqlSessionFactory != null) {
                DATABASE_TYPE = sqlSessionFactory.getConfiguration().getDatabaseId();
            }
        }
        if (DATABASE_TYPE == null) {
            log.warn("无法识别数据库类型，请检查数据源配置:spring.datasource.url等");
        }
        return DATABASE_TYPE;
    }
}
