package com.op.system.service.impl;

import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.op.common.core.utils.DateUtils;
import com.op.common.core.utils.StringUtils;
import com.op.common.core.utils.uuid.IdUtils;
import com.op.common.datasource.creator.DynamicDatasourceCreator;
import com.op.system.api.domain.SysUser;
import com.op.system.domain.SysDatasource;
import com.op.system.mapper.SysDatasourceMapper;
import com.op.system.service.ISysDatasourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 工厂数据库Service业务层处理
 *
 * @author sf
 * @date 2023-05-18
 */
@Service
public class SysDatasourceServiceImpl implements ISysDatasourceService {
    private static final Logger log = LoggerFactory.getLogger(SysDatasourceServiceImpl.class);
    @Autowired
    private SysDatasourceMapper sysDatasourceMapper;
    @Value("${sqlserve.prev}")
    private String mysqlPrev;
    @Value("${sqlserve.affter}")
    private String mysqlAffter;
    @Value("${sqlserve.poolName.prev}")
    private String poolNamePrev;
    @Value("${sqlserve.driver}")
    private String driver;
    @Resource
    private DynamicDatasourceCreator dynamicDatasourceCreator;

    /**
     * 查询工厂数据库
     *
     * @param id 工厂数据库主键
     * @return 工厂数据库
     */
    @Override
    public SysDatasource selectSysDatasourceById(String id) {
        return sysDatasourceMapper.selectSysDatasourceById(id);
    }

    /**
     * 查询工厂数据库列表
     *
     * @param sysDatasource 工厂数据库
     * @return 工厂数据库
     */
    @Override
    public List<SysDatasource> selectSysDatasourceList(SysDatasource sysDatasource) {
        return sysDatasourceMapper.selectSysDatasourceList(sysDatasource);
    }

    /**
     * 新增工厂数据库
     *
     * @param sysDatasource 工厂数据库
     * @return 结果
     */
    @Override
    public int insertSysDatasource(SysDatasource sysDatasource) {
        sysDatasource.setCreateTime(DateUtils.getNowDate());
        sysDatasource.setId(IdUtils.randomUUID().replace("-",""));
        sysDatasource.setDriveClassName(driver);
        if(StringUtils.isNotEmpty(sysDatasource.getIpPort())){
            sysDatasource.setUrl(mysqlPrev+sysDatasource.getIpPort().split("/")[0]
                               +mysqlAffter+sysDatasource.getIpPort().split("/")[1]);
        }
        if(sysDatasource.getDeptId()!=null){
            if(StringUtils.isNotEmpty(sysDatasource.getSystemType())){
                sysDatasource.setPoolName(poolNamePrev+"_"+sysDatasource.getSystemType()+"_"+sysDatasource.getDeptId());
            }else{
                sysDatasource.setPoolName(poolNamePrev+"_"+sysDatasource.getDeptId());
            }
        }

        return sysDatasourceMapper.insertSysDatasource(sysDatasource);
    }

    /**
     * 修改工厂数据库
     *
     * @param sysDatasource 工厂数据库
     * @return 结果
     */
    @Override
    public int updateSysDatasource(SysDatasource sysDatasource) {

        //修改之后status->1 不生效，需要重新测试链接才生效
        sysDatasource.setStatus("1");
        sysDatasource.setUpdateTime(DateUtils.getNowDate());
        return sysDatasourceMapper.updateSysDatasource(sysDatasource);
    }

    /**
     * 批量删除工厂数据库
     *
     * @param ids 需要删除的工厂数据库主键
     * @return 结果
     */
    @Override
    public int deleteSysDatasourceByIds(String[] ids) {
        return sysDatasourceMapper.deleteSysDatasourceByIds(ids);
    }

    /**
     * 删除工厂数据库信息
     *
     * @param id 工厂数据库主键
     * @return 结果
     */
    @Override
    public int deleteSysDatasourceById(String id) {
        return sysDatasourceMapper.deleteSysDatasourceById(id);
    }

    @Override
    public List<SysDatasource> selectAllocatedList(SysDatasource sysDatasource) {
        return sysDatasourceMapper.selectAllocatedList(sysDatasource);
    }

    @Override
    public List<SysUser> selectUnallocatedList(SysUser user) {
        return sysDatasourceMapper.selectUnallocatedList(user);
    }

    @Override
    public void checkRoleDataScope(String datasourceId) {
//        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
//            SysRole role = new SysRole();
//            role.setRoleId(roleId);
//            List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
//            if (StringUtils.isEmpty(roles)) {
//                throw new ServiceException("没有权限访问角色数据！");
//            }
//        }
    }

    @Override
    public int insertAuthUsers(String datasourceId, Long[] userIds) {
        // 新增用户与数据源管理
        List<SysDatasource> list = new ArrayList<SysDatasource>();
        for (Long userId : userIds) {
            SysDatasource ur = new SysDatasource();
            ur.setUserId(userId.toString());
            ur.setDatasourceId(datasourceId.toString());
            list.add(ur);
        }
        return sysDatasourceMapper.batchUserDB(list);
    }

    @Override
    public int deleteAuthUser(SysDatasource sysDatasource) {
        return sysDatasourceMapper.deleteUserRoleInfo(sysDatasource);
    }

    @Override
    public int deleteAuthUsers(String datasourceId, Long[] userIds) {
        return sysDatasourceMapper.deleteUserRoleInfos(datasourceId, userIds);
    }

    @Override
    public String changeDBStatus(SysDatasource sd) {

        SysDatasource sysDatasource = sysDatasourceMapper.selectSysDatasourceById(sd.getDatasourceId());

        if(sysDatasource == null){
            return "数据库链接不存在";
        }
        try {
            Class.forName(sysDatasource.getDriveClassName());
            Connection conn = DriverManager.getConnection(sysDatasource.getUrl(),
                    sysDatasource.getUserName(),
                    sysDatasource.getPassword());
            if (conn != null) {
                if (conn.isClosed()) {
                    log.error("[{}]数据库连接检测异常:[{}]",sysDatasource.getPoolName());
                    return "数据库链接异常，请检查数据库基本信息。";//假如打不开数据库链接则跳过初始化数据库
                } else {
                    //说明数据库可以正常连接,关闭测试连接
                    conn.close();
                    log.info("[{}]数据库连接检测正常", sysDatasource.getPoolName());
                }
            } else {
                log.error("[{}]数据库连接检测异常:[{}]", sysDatasource.getPoolName());
                return "数据库链接异常，请检查数据库基本信息。";
            }

            sysDatasource.setUpdateTime(DateUtils.getNowDate());
            sysDatasource.setStatus("0");//激活
            sysDatasourceMapper.updateSysDatasource(sysDatasource);

            DataSourceProperty dataSourceProperty = new DataSourceProperty();
            dataSourceProperty.setUrl(sysDatasource.getUrl());
            dataSourceProperty.setUsername(sysDatasource.getUserName());
            dataSourceProperty.setPassword(sysDatasource.getPassword());
            dataSourceProperty.setDriverClassName(sysDatasource.getDriveClassName());
            dataSourceProperty.setPoolName(sysDatasource.getPoolName());// 这是数据源的key
            dataSourceProperty.setLazy(false);
            dynamicDatasourceCreator.createDynamicDataSource(dataSourceProperty);

            return "数据库链接测试成功，数据库链接状态正常";
        }catch (ClassNotFoundException | SQLException classNotFoundException){
            return "数据库链接异常，请检查数据库基本信息。";
        }

    }

}
