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

import cn.datax.common.core.DataConstant;
import cn.datax.common.database.DataSourceFactory;
import cn.datax.common.database.DbQuery;
import cn.datax.common.database.constants.DbQueryProperty;
import cn.datax.common.database.core.DbColumn;
import cn.datax.common.database.core.DbTable;
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.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.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 数据源信息表 服务实现类
 * </p>
 *
 * @author yuwei
 * @since 2020-03-14
 */
@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);
        dataSource.setSourceSync(Integer.valueOf(DataConstant.TrueOrFalse.FALSE.getKey()));
        dataSourceDao.insert(dataSource);
    }

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

    @Override
    public DataSourceEntity getDataSourceById(String id) {
        DataSourceEntity dataSourceEntity = super.getById(id);
        return dataSourceEntity;
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDataSourceBatch(List<String> ids) {
        dataSourceDao.deleteBatchIds(ids);
    }

    @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(), dbSchema.getSid());
        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(), dbSchema.getSid());
        DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
        return dbQuery;
    }

    @Override
    public List<DbTable> getDbTables(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(), dbSchema.getSid());
        DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
        List<DbTable> tables = dbQuery.getTables(dbSchema.getDbName());
        return tables;
    }

    @Override
    public List<DbColumn> getDbTableColumns(String id, String tableName) {
        DataSourceEntity dataSource = getById(id);
        DbSchema dbSchema = dataSource.getDbSchema();
        DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(),
                dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid());
        DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
        List<DbColumn> columns = dbQuery.getTableColumns(dbSchema.getDbName(), tableName);
        return columns;
    }

    @Override
    public void updateDataSourceSyncById(String id) {
        DataSourceEntity dataSource = new DataSourceEntity();
        dataSource.setId(id);
        dataSource.setSourceSync(Integer.valueOf(DataConstant.TrueOrFalse.TRUE.getKey()));
        dataSourceDao.updateById(dataSource);
    }
}
