package com.muyu.cloud.common.many.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.muyu.cloud.common.saas.domain.model.EntInfo;
import com.muyu.cloud.common.many.datasource.factory.DruidDataSourceFactory;
import com.muyu.cloud.common.many.datasource.domain.model.DataSourceInfo;
import com.muyu.cloud.common.many.datasource.role.DynamicDataSource;
import com.muyu.cloud.common.saas.exception.SaaSException;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.SpringUtils;
import com.muyu.common.system.domain.SysEnt;
import com.muyu.common.system.remote.RemoteUserService;
import lombok.extern.log4j.Log4j2;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @Author: DongZeLiang
 * @date: 2024/6/3
 * @Description: 多数据源
 * @Version: 1.0
 */
@Log4j2
@AutoConfiguration(before = {MybatisPlusAutoConfiguration.class, MybatisAutoConfiguration.class})
@Component
public class ManyDataSource implements ApplicationRunner{


    private List<EntInfo> dataSourceInfoList(){
        RemoteUserService remoteUserService = SpringUtils.getBean(RemoteUserService.class);
        Result<List<SysEnt>> listResult = remoteUserService.list(new SysEnt());
        if (listResult==null){
            throw new SaaSException("saas远调数据源错误");
        }
        List<SysEnt> data = listResult.getData();
        System.out.println(data);
        if (listResult.getCode() == Result.SUCCESS && data !=null){
            List<EntInfo> list = new ArrayList<>();
            for (SysEnt row : data) {
                list.add(
                        EntInfo.builder()
                                .entCode(row.getEntCode())
                                .dbName(row.getDbName())
                                .ip(row.getIp())
                                .port(row.getPort())
                                .userName(row.getUserName())
                                .password(row.getPassword())
                                .build()
                );
            }
            return list;
        }else {
            log.error("远调数据源错误,远调数据为：{}", JSON.toJSONString(listResult));
            return null;
        }
    }


    @Bean
    public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) {
        // 企业列表 企业CODE，端口，IP
        Map<Object, Object> dataSourceMap = new HashMap<>();
        Objects.requireNonNull(dataSourceInfoList())
                .stream()
                .map(DataSourceInfo::hostAndPortBuild)
                .forEach(dataSourceInfo -> {
                    dataSourceMap.put(dataSourceInfo.getKey(), druidDataSourceFactory.create(dataSourceInfo));
                });
        //设置动态数据源
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
//        dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        //将数据源信息备份在defineTargetDataSources中
        dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
        log.info("动态数据源加载完成,持有key：{}",dynamicDataSource.getKeys());
        return dynamicDataSource;
    }

    @Override
    public void run(ApplicationArguments args) {
        DruidDataSourceFactory druidDataSourceFactory = SpringUtils.getBean(DruidDataSourceFactory.class);
        DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
        for (EntInfo entInfo : dataSourceInfoList()) {
            DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(entInfo);
            DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo);
            dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource);
            log.info("存储数据连接池为：key:{}",dataSourceInfo.getKey());
        }
    }

//    @Bean
//    public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception {
//        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
//        sessionFactory.setDataSource(dataSource);
//        return sessionFactory.getObject();
//    }
}
