package cn.fateverse.query.enums;

import cn.fateverse.query.factory.DynamicDataSourceFactory;
import cn.fateverse.query.factory.impl.MariaDynamicDataSourceFactory;
import cn.fateverse.query.factory.impl.MySqlDynamicDataSourceFactory;
import cn.fateverse.query.factory.impl.OracleDynamicDataSourceFactory;
import cn.fateverse.query.factory.impl.PostgresDynamicDataSourceFactory;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

/**
 * @author Clay
 * @date 2023-07-16
 */
public enum DynamicSourceEnum {


    /**
     * 数据库状态
     */
    MYSQL("mysql", "com.mysql.cj.jdbc.Driver", MySqlDynamicDataSourceFactory.class),
    MARIADB("mariadb", "org.mariadb.jdbc.Driver", MariaDynamicDataSourceFactory.class),
    ORACLE("oracle", "oracle.jdbc.driver.OracleDriver", OracleDynamicDataSourceFactory.class),
    POSTGRES("postgres", "org.postgresql.Driver", PostgresDynamicDataSourceFactory.class),
    ;


    private final String type;

    private final String drive;

    private final Class<? extends DynamicDataSourceFactory> clazz;

    private volatile DynamicDataSourceFactory dynamicDataSourceFactory;


    DynamicSourceEnum(String type, String drive, Class<? extends DynamicDataSourceFactory> clazz) {
        this.type = type;
        this.drive = drive;
        this.clazz = clazz;
    }

    public String getType() {
        return type;
    }

    public String getDrive() {
        return drive;
    }

    public DynamicDataSourceFactory getDynamicDataSourceFactory() {
        if (null == dynamicDataSourceFactory) {
            synchronized (this) {
                if (null == dynamicDataSourceFactory) {
                    try {
                        dynamicDataSourceFactory = clazz.getDeclaredConstructor().newInstance();
                    } catch (NoSuchMethodException | InvocationTargetException | InstantiationException |
                             IllegalAccessException e) {
                        e.printStackTrace();
                        throw new RuntimeException("初始化实例失败!");
                    }
                }
            }
        }
        return dynamicDataSourceFactory;
    }


    public static DynamicSourceEnum getType(String typeName){
        return Arrays.stream(DynamicSourceEnum.values()).filter(e->e.getType().equals(typeName)).findFirst().orElse(null);
    }
}
