package com.artfess.base.jdbc;

import com.alibaba.druid.pool.DruidDataSource;
import com.artfess.base.datasource.impl.DefaultDatabaseContext;
import com.artfess.base.exception.ApplicationException;
import com.artfess.base.util.AppUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 *
 */
@Repository("JdbcDaoImpl")
@Slf4j
public class JdbcDaoImpl implements JdbcDao {

    //缓存连接不用每次都创建连接池
   private static Map<String,DruidDataSource> JdbcDruidDataSource=new HashMap<>();

   public JdbcTemplate initJdbcTemplate(String alias){
        JdbcTemplate jdbcTemplate;
        try {
            if (StringUtils.isEmpty(alias)) {
                throw new ApplicationException("创建属性不能空");
            }
            if (JdbcDruidDataSource.containsKey(alias)) {
                //jdbcTemplate = JdbcTemplateMap.get(dataSourceId);
                DruidDataSource druidDataSource=JdbcDruidDataSource.get(alias);
                jdbcTemplate = new JdbcTemplate(druidDataSource);
            } else {
                DefaultDatabaseContext context = AppUtil.getBean(DefaultDatabaseContext.class);
                DruidDataSource druidDataSource = (DruidDataSource)context.getDataSourceByAlias(alias);

                jdbcTemplate = new JdbcTemplate(druidDataSource);
                //JdbcTemplateMap.put(dataSourceId, jdbcTemplate);
                JdbcDruidDataSource.put(alias, druidDataSource);
            }
        }catch (Exception e){
            throw new ApplicationException("创建连接失败");
        }
        return jdbcTemplate;
    }


    //修改数据源配置时，同步修改数据连接池
    public boolean checkConnection(String alias,String url,String userName,String pwd,String driver) {
        boolean isConnection=false;
        Connection con= null;
        try {
            Class.forName(driver);
            System.out.println("数据库驱动加载成功");
        } catch(ClassNotFoundException e){
            //e.printStackTrace();
            log.error("数据库驱动加载失败", e.getMessage());
        }
        try {
            con = DriverManager.getConnection(url,userName,pwd);
            isConnection=true;
            System.out.println("数据库连接成功");
        } catch (SQLException e) {
            log.error("数据库链接失败", e.getMessage());
            if (JdbcDruidDataSource.containsKey(alias)) {
                JdbcDruidDataSource.get(alias).close();
                //JdbcTemplateMap.remove(dataSourceId);
            }
            throw new ApplicationException("数据库链接失败:"+e.getMessage(),e);
        }finally {
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e1) {
                    log.error(e1.getMessage(),e1);
                }
            }
        }
        return isConnection;
    }

    public void removeCache(String key){
        //关闭数据源连接
        DruidDataSource druidDataSource = JdbcDruidDataSource.get(key);
        try {
            if (druidDataSource != null && !druidDataSource.isClosed()) {
                druidDataSource.getConnection().commit();
                druidDataSource.getConnection().close();
                druidDataSource.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //清空缓存
            JdbcDruidDataSource.remove(key);
        }

    }


    public DataSource getDataSource(JdbcTemplate jdbcTemplate) {
        return jdbcTemplate.getDataSource();
    }


    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void batchUpdate(JdbcTemplate jdbcTemplate,String[] sql) throws ApplicationException {
        jdbcTemplate.batchUpdate(sql);
    }

    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public int[] batchUpdateData(JdbcTemplate jdbcTemplate,String sql, List<Object[]> dataSet) throws ApplicationException {
        return jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Object[] objArr=dataSet.get(i);
                for(int j=0;j<objArr.length;j++){
                    if(objArr[j]!=null && "null".equalsIgnoreCase(objArr[j].toString())){
                        ps.setString((j + 1), "");
                    }else {
                        ps.setObject((j + 1), objArr[j]);
                    }
                }
            }
            public int getBatchSize() {
                return dataSet.size();
            }
        });
    }
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void batchUpdate(JdbcTemplate jdbcTemplate,String sql, List<Object[]> dataSet) throws ApplicationException {
        a(sql, dataSet);
        jdbcTemplate.batchUpdate(sql);
    }




    private String a(String sql, List<Object[]> dataSet)throws ApplicationException {
        String str = "";
        if (dataSet != null) {
            Object[] arrayOfObject = null;
            for (Iterator<Object[]> i$ = dataSet.iterator(); i$.hasNext(); arrayOfObject = i$.next()) ;
        } else {
            log.info(sql);
        }
        return str;
    }

}