/*
 * Copyright (c) 2023 codvision.com All Rights Reserved.
 */

package com.codvision.db.versionctl;

import cn.hutool.core.util.StrUtil;
import com.codvision.commoncore.exception.BusinessException;
import com.codvision.db.config.DBVCTLProps;
import com.codvision.db.utils.DbUtil;
import org.springframework.core.env.Environment;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * 数据库版本控制器
 *
 * @author lingee
 * @date 2023/12/5
 */
public class DbVersionCtlInitializer {

    @Resource
    private DBVCTLProps dbvctlProps;

    @Resource
    protected Environment env;

    @PostConstruct
    public void init() {
        // 开启自动控制时才会自动执行数据库版本升级
        if (dbvctlProps.getEnabled()) {
            dbVersionCtl();
        }
    }

    /**
     * 用于手动执行数据库版本升级
     */
    public void dbVersionCtlManual() {
        if (!dbvctlProps.getEnabled()) {
            dbVersionCtl();
        }
    }

    private void dbVersionCtl() {
        // 如果已经配置了spring的数据源，则可以直接使用它们而不必重复配置JDBC连接属性
        String jdbcClass = env.getProperty("spring.datasource.driver-class-name");
        String jdbcUrl = env.getProperty("spring.datasource.url");
        String jdbcUser = env.getProperty("spring.datasource.username");
        String jdbcPwd = env.getProperty("spring.datasource.password");

        if (StrUtil.isBlank(jdbcUrl)) {
            throw new BusinessException("未配置数据库连接");
        }

        DbVersionCtlProps dbVersionCtlProps = new DbVersionCtlProps();
        dbVersionCtlProps.setBaselineBusinessSpaceAndVersions(dbvctlProps.getBaselineBusinessSpaceAndVersions());
        dbVersionCtlProps.setDriverClassName(jdbcClass);
        dbVersionCtlProps.setUrl(jdbcUrl);
        dbVersionCtlProps.setUsername(jdbcUser);
        dbVersionCtlProps.setPassword(jdbcPwd);

        String existTblQuerySql = "";
        switch (DbUtil.getDatabaseType(jdbcUrl)) {
            case mysql:
                existTblQuerySql = "show tables";
                break;
            case postgresql:
                existTblQuerySql = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema')";
                break;
        }
        dbVersionCtlProps.setExistTblQuerySql(existTblQuerySql);
        dbVersionCtlProps.setBaselineReset(dbvctlProps.getBaselineReset() ? "y" : "n");
        dbVersionCtlProps.setBaselineResetConditionSql(dbvctlProps.getBaselineResetConditionSql());

        DbVersionCtl dbVersionCtl = new DbVersionCtl(dbVersionCtlProps);
        dbVersionCtl.doDBVersionControl();
    }
}
