package cn.datax.service.data.factory.service.impl;

import cn.datax.common.database.DataSourceFactory;
import cn.datax.common.database.DbQuery;
import cn.datax.common.database.constants.DbQueryProperty;
import cn.datax.service.data.factory.api.dto.DataSourceDto;
import cn.datax.service.data.factory.api.dto.DbSchema;
import cn.datax.service.data.factory.api.entity.DataSourceEntity;
import cn.datax.service.data.factory.api.vo.DataSourceVo;
import cn.datax.service.data.factory.dao.DataSourceDao;
import cn.datax.service.data.factory.service.DataSourceService;
import cn.datax.service.data.factory.mapstruct.DataSourceMapper;
import cn.datax.common.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 数据源信息表 服务实现类
 * </p>
 *
 * @author yuwei
 * @since 2020-03-14
 */
@CacheConfig(cacheNames = "data:factory:sources")
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DataSourceServiceImpl extends BaseServiceImpl<DataSourceDao, DataSourceEntity> implements DataSourceService {

    @Autowired
    private DataSourceDao dataSourceDao;

    @Autowired
    private DataSourceMapper dataSourceMapper;

    @Autowired
    private DataSourceFactory dataSourceFactory;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDataSource(DataSourceDto dataSourceDto) {
        DataSourceEntity dataSource = dataSourceMapper.toEntity(dataSourceDto);
        dataSourceDao.insert(dataSource);
    }

    @CachePut(key = "#p0.id")
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDataSource(DataSourceDto dataSourceDto) {
        DataSourceEntity dataSource = dataSourceMapper.toEntity(dataSourceDto);
        dataSourceDao.updateById(dataSource);
    }

    @Cacheable(key = "#id", unless = "#result == null")
    public DataSourceVo getDataSourceById(String id) {
        DataSourceEntity dataSourceEntity = super.getById(id);
        return dataSourceMapper.toVO(dataSourceEntity);
    }

    @CacheEvict(key = "#id")
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDataSourceById(String id) {
        dataSourceDao.deleteById(id);
    }

    @Override
    public DbQuery checkConnection(DataSourceDto dataSourceDto) {
        DataSourceEntity dataSource = dataSourceMapper.toEntity(dataSourceDto);
        DbSchema dbSchema = dataSource.getDbSchema();
        DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(),
                dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName());
        DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
        return dbQuery;
    }

    @Override
    public DbQuery getDbQuery(String id) {
        DataSourceEntity dataSource = getById(id);
        DbSchema dbSchema = dataSource.getDbSchema();
        DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(),
                dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName());
        DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
        return dbQuery;
    }
}
