package com.qiaoba.module.tenant.service.impl;

import cn.hutool.core.util.StrUtil;
import com.qiaoba.api.tenant.entity.SysTenant;
import com.qiaoba.api.tenant.entity.SysTenantDatasource;
import com.qiaoba.api.tenant.entity.param.SysTenantDatasourceParam;
import com.qiaoba.api.tenant.entity.param.SysTenantParam;
import com.qiaoba.common.base.enums.BaseEnum;
import com.qiaoba.common.base.exception.ServiceException;
import com.qiaoba.common.database.entity.DynamicDataSource;
import com.qiaoba.common.database.service.DynamicDatasourceService;
import com.qiaoba.module.tenant.service.SysTenantDatasourceService;
import com.qiaoba.module.tenant.service.SysTenantService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 动态数据源接口
 *
 * @author ailanyin
 * @version 1.0
 * @since 2023/6/9 13:16
 */
@Service
@RequiredArgsConstructor
public class DynamicDatasourceServiceImpl implements DynamicDatasourceService {

    private final SysTenantDatasourceService sysTenantDatasourceService;
    private final SysTenantService sysTenantService;

    @Override
    public Map<String, List<DynamicDataSource>> loadAllTenantDatasource() {
        Map<String, List<DynamicDataSource>> datasourceMap = new LinkedHashMap<>();
        List<SysTenant> sysTenants = sysTenantService.selectList(SysTenantParam.buildNormalSelectParam());
        for (SysTenant sysTenant : sysTenants) {
            List<SysTenantDatasource> datasourceList = sysTenantDatasourceService.selectList(new SysTenantDatasourceParam(sysTenant.getTenantId()));
            datasourceMap.put(sysTenant.getTenantId(), transformList(datasourceList));

        }
        return datasourceMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changePrimaryDatasource(String tenantId, String datasourceId) {
        // 将该数据源设置为主要数据源
        SysTenantDatasource sysTenantDatasource = new SysTenantDatasource();
        sysTenantDatasource.setDatasourceId(datasourceId);
        sysTenantDatasource.setIsPrimary(BaseEnum.YES.getCode());
        sysTenantDatasourceService.updateById(sysTenantDatasource);
        // 将该租户下的其他数据源设置为非主要数据源
        sysTenantDatasourceService.setBackupDatasourceExcludeId(tenantId, datasourceId);
    }

    @Override
    public DynamicDataSource selectByIp(String tenantId, String ip) {
        SysTenantDatasource sysTenantDatasource = sysTenantDatasourceService.selectByIp(tenantId, ip);
        if (Objects.isNull(sysTenantDatasource)) {
            throw new ServiceException(StrUtil.format("未找到数据源,查询方式: {}", ip));
        }
        return transform(sysTenantDatasource);
    }

    private List<DynamicDataSource> transformList(List<SysTenantDatasource> datasourceList) {
        List<DynamicDataSource> dynamicDataSourceList = new ArrayList<>();
        for (SysTenantDatasource datasource : datasourceList) {
            dynamicDataSourceList.add(transform(datasource));
        }
        return dynamicDataSourceList;
    }

    private DynamicDataSource transform(SysTenantDatasource datasource) {
        return sysTenantDatasourceService.transform(datasource);
    }
}
