package cn.fateverse.query.factory.impl;

import cn.fateverse.query.entity.DataSourceManage;
import cn.fateverse.query.entity.DynamicPage;
import cn.fateverse.query.enums.DynamicSourceEnum;
import cn.fateverse.query.submeter.datasource.SubmeterDataSource;
import cn.fateverse.query.utils.MyBatisResourceUtils;
import cn.hutool.core.util.StrUtil;
import cn.fateverse.common.core.entity.PageInfo;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.core.utils.TableSupport;
import cn.fateverse.common.mybatis.utils.PageUtils;
import cn.fateverse.query.factory.DynamicDataSourceFactory;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.core.io.Resource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Clay
 * @date 2023-07-24
 */
@Slf4j
public abstract class AbstractDynamicDataSourceFactory implements DynamicDataSourceFactory {

    public SqlSessionFactory getSqlSessionFactory(DataSourceManage dataSourceManage, String mapperPath) {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        //获取需要的xml文件
        Resource[] resources = MyBatisResourceUtils.getResources(mapperPath);
        sessionFactoryBean.setMapperLocations(resources);
        DynamicSourceEnum mysqlEnum = dataSourceManage.getType();
        String baseUrl;
        if (1 == dataSourceManage.getConfigType()) {
            baseUrl = getDataBaseUrl(dataSourceManage);
        } else {
            baseUrl = dataSourceManage.getUrl();
        }
        //todo 后续分表查询可将数据源替换为新的数据源即可
        DataSource dataSource = new UnpooledDataSource(mysqlEnum.getDrive(), baseUrl,
                dataSourceManage.getUsername(), dataSourceManage.getPassword());
//        sessionFactoryBean.setDataSource(new SubmeterDataSource(dataSource));
        sessionFactoryBean.setDataSource(dataSource);
        SqlSessionFactory sqlSessionFactory;
        try {
            sqlSessionFactory = sessionFactoryBean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return sqlSessionFactory;
    }


    @Override
    public DynamicPage getDynamicPage() {
        PageInfo pageInfo = TableSupport.buildPageRequest();
        Integer startNum = PageUtils.getStartSize(pageInfo);
        Integer endNum = startNum + pageInfo.getPageSize();
        return DynamicPage.builder()
                .startNum(startNum)
                .endNum(endNum)
                .build();
    }

    @Override
    public Map<String, Object> getParams(DataSourceManage dataSourceManage) {
        return new HashMap<>();
    }


    public JSONObject checkParam(String paramStr, String msg, String... keys) {
        if (StrUtil.isBlank(paramStr)) {
            throw new CustomException(msg);
        }
        JSONObject params;
        try {
            params = JSON.parseObject(paramStr);
            for (String key : keys) {
                if (StrUtil.isBlank(params.getString(key))) {
                    log.error(key + "is blank");
                    throw new CustomException(msg);
                }
            }
        } catch (JSONException e) {
            throw new CustomException(msg);
        }
        return params;
    }

}
