package com.seeyon.apps.src_ydctdatasync.dao;

import com.seeyon.apps.src_ydctdatasync.datasource.DataSource;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.util.StringUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyJdbcAgent {

    private DataSource dataSource;

    public MyJdbcAgent() {
    }

    public MyJdbcAgent(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Object executeWithOneParam(String sqlString, Object param) throws BusinessException, SQLException {
        List params = new ArrayList();
        params.add(param);
        return this.execute(sqlString, (List)params);
    }

    public Object execute(String sqlString, List params) throws SQLException {
        String sqlOpt = sqlString.trim().substring(0, 6).toLowerCase();
        String tmpStr = sqlString;
        try (Connection connection = dataSource.getLocalConnection()){
            for (int i = 0; i < params.size(); ++i) {
                Object param = params.get(i);
                String newString = param == null ? "null" : "'" + param + "'";
                tmpStr = StringUtil.replace(tmpStr, "?", newString, 1);
            }
            if (!sqlString.startsWith("WITH _pagingRows") && !sqlOpt.startsWith("select") && !sqlOpt.startsWith("show")) {
                if (!sqlOpt.startsWith("update") && !sqlOpt.startsWith("delete") && !sqlOpt.startsWith("insert")) {
                    return this.executeOther(sqlString, params, connection);
                } else {
                    return this.update(sqlString, params, connection);
                }
            } else {

                return this.query(sqlString, params, connection);
            }
        }

    }



    private boolean executeOther(String sql, List params,Connection connection) throws SQLException {
        try (PreparedStatement pst = connection.prepareStatement(sql)) {
            // 设置参数
            for (int i = 0; params != null && i < params.size(); i++) {
               pst.setObject(i + 1, params.get(i));
            }
            return pst.execute();
        }
    }

    private int update(String sql, List params,Connection connection) throws SQLException {
        try (PreparedStatement pst = connection.prepareStatement(sql)) {
            // 设置参数
            for (int i = 0; params != null && i < params.size(); i++) {
                pst.setObject(i + 1, params.get(i));
            }
            return pst.executeUpdate();
        }
    }

    private List<Map<String, Object>> query(String sql, List params, Connection connection) throws SQLException {
        List<Map<String, Object>> resultList = new ArrayList<>();
        try (PreparedStatement pst = connection.prepareStatement(sql)) {
            // 设置参数
            for (int i = 0; params != null && i < params.size(); i++) {
                pst.setObject(i + 1, params.get(i));
            }
            // 执行查询
            try (ResultSet resultSet = pst.executeQuery()) {
                // 获取元数据
                ResultSetMetaData metaData = resultSet.getMetaData();
                int columnCount = metaData.getColumnCount();

                // 遍历结果集
                while (resultSet.next()) {
                    Map<String, Object> rowMap = new HashMap<>();
                    for (int i = 1; i <= columnCount; i++) {
                        String columnName = metaData.getColumnLabel(i);
                        Object columnValue = resultSet.getObject(i);
                        rowMap.put(columnName, columnValue);
                    }
                    resultList.add(rowMap);
                }
            }
        }
        return resultList;
    }

}
